diff --git a/.gitignore b/.gitignore index faf70c4c24..7a7e2d9ef0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.coverprofile node_modules/ +vendor \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 8bb0e9cb55..9154f35bac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,26 +2,33 @@ language: go sudo: false dist: trusty osx_image: xcode8.3 -go: 1.11.x +go: + - 1.11.x + - 1.12.x os: -- linux -- osx + - linux + - osx cache: directories: - - node_modules + - node_modules before_script: -- go get github.com/urfave/gfmrun/... || true -- go get golang.org/x/tools/cmd/goimports -- if [ ! -f node_modules/.bin/markdown-toc ] ; then - npm install markdown-toc ; - fi + - go get github.com/shurcooL/vfsgen || true + - go get github.com/shurcooL/httpfs/union || true + - go get github.com/urfave/gfmrun/... || true + - go get golang.org/x/tools/cmd/goimports + - if [ ! -f node_modules/.bin/markdown-toc ] ; then + npm install markdown-toc ; + fi script: -- ./runtests gen -- ./runtests vet -- ./runtests test -- ./runtests gfmrun -- ./runtests toc + - go run build.go generate + - go run build.go vet + - go run build.go test + - go run build.go gfmrun + - go run build.go toc + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index 17d0900583..001d76f606 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ cli [![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) + [![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) [![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli) [![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli) @@ -888,7 +889,9 @@ Calling `App.Run` will not automatically call `os.Exit`, which means that by default the exit code will "fall through" to being `0`. An explicit exit code may be set by returning a non-nil error that fulfills `cli.ExitCoder`, *or* a `cli.MultiError` that includes an error that fulfills `cli.ExitCoder`, e.g.: - + ``` go package main diff --git a/altsrc/altsrc.go b/altsrc/altsrc.go deleted file mode 100644 index ac34bf633b..0000000000 --- a/altsrc/altsrc.go +++ /dev/null @@ -1,3 +0,0 @@ -package altsrc - -//go:generate python ../generate-flag-types altsrc -i ../flag-types.json -o flag_generated.go diff --git a/altsrc/flag_generated.go b/altsrc/flag_generated.go index 08170ca164..e568872143 100644 --- a/altsrc/flag_generated.go +++ b/altsrc/flag_generated.go @@ -1,13 +1,12 @@ +// Code generated by fg; DO NOT EDIT. + package altsrc import ( "flag" - "github.com/urfave/cli" ) -// WARNING: This file is generated! - // BoolFlag is the flag type that wraps cli.BoolFlag to allow // for other values to be specified type BoolFlag struct { @@ -17,18 +16,18 @@ type BoolFlag struct { // NewBoolFlag creates a new BoolFlag func NewBoolFlag(fl cli.BoolFlag) *BoolFlag { - return &BoolFlag{BoolFlag: fl, set: nil} + return &BoolFlag{ BoolFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped BoolFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped BoolFlag.Apply func (f *BoolFlag) Apply(set *flag.FlagSet) { f.set = set f.BoolFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped BoolFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped BoolFlag.ApplyWithError func (f *BoolFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.BoolFlag.ApplyWithError(set) @@ -43,18 +42,18 @@ type BoolTFlag struct { // NewBoolTFlag creates a new BoolTFlag func NewBoolTFlag(fl cli.BoolTFlag) *BoolTFlag { - return &BoolTFlag{BoolTFlag: fl, set: nil} + return &BoolTFlag{ BoolTFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped BoolTFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped BoolTFlag.Apply func (f *BoolTFlag) Apply(set *flag.FlagSet) { f.set = set f.BoolTFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped BoolTFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped BoolTFlag.ApplyWithError func (f *BoolTFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.BoolTFlag.ApplyWithError(set) @@ -69,18 +68,18 @@ type DurationFlag struct { // NewDurationFlag creates a new DurationFlag func NewDurationFlag(fl cli.DurationFlag) *DurationFlag { - return &DurationFlag{DurationFlag: fl, set: nil} + return &DurationFlag{ DurationFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped DurationFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped DurationFlag.Apply func (f *DurationFlag) Apply(set *flag.FlagSet) { f.set = set f.DurationFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped DurationFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped DurationFlag.ApplyWithError func (f *DurationFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.DurationFlag.ApplyWithError(set) @@ -95,18 +94,18 @@ type Float64Flag struct { // NewFloat64Flag creates a new Float64Flag func NewFloat64Flag(fl cli.Float64Flag) *Float64Flag { - return &Float64Flag{Float64Flag: fl, set: nil} + return &Float64Flag{ Float64Flag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped Float64Flag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped Float64Flag.Apply func (f *Float64Flag) Apply(set *flag.FlagSet) { f.set = set f.Float64Flag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped Float64Flag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped Float64Flag.ApplyWithError func (f *Float64Flag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.Float64Flag.ApplyWithError(set) @@ -121,18 +120,18 @@ type GenericFlag struct { // NewGenericFlag creates a new GenericFlag func NewGenericFlag(fl cli.GenericFlag) *GenericFlag { - return &GenericFlag{GenericFlag: fl, set: nil} + return &GenericFlag{ GenericFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped GenericFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped GenericFlag.Apply func (f *GenericFlag) Apply(set *flag.FlagSet) { f.set = set f.GenericFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped GenericFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped GenericFlag.ApplyWithError func (f *GenericFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.GenericFlag.ApplyWithError(set) @@ -147,18 +146,18 @@ type Int64Flag struct { // NewInt64Flag creates a new Int64Flag func NewInt64Flag(fl cli.Int64Flag) *Int64Flag { - return &Int64Flag{Int64Flag: fl, set: nil} + return &Int64Flag{ Int64Flag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped Int64Flag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped Int64Flag.Apply func (f *Int64Flag) Apply(set *flag.FlagSet) { f.set = set f.Int64Flag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped Int64Flag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped Int64Flag.ApplyWithError func (f *Int64Flag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.Int64Flag.ApplyWithError(set) @@ -173,18 +172,18 @@ type IntFlag struct { // NewIntFlag creates a new IntFlag func NewIntFlag(fl cli.IntFlag) *IntFlag { - return &IntFlag{IntFlag: fl, set: nil} + return &IntFlag{ IntFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped IntFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped IntFlag.Apply func (f *IntFlag) Apply(set *flag.FlagSet) { f.set = set f.IntFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped IntFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped IntFlag.ApplyWithError func (f *IntFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.IntFlag.ApplyWithError(set) @@ -199,18 +198,18 @@ type IntSliceFlag struct { // NewIntSliceFlag creates a new IntSliceFlag func NewIntSliceFlag(fl cli.IntSliceFlag) *IntSliceFlag { - return &IntSliceFlag{IntSliceFlag: fl, set: nil} + return &IntSliceFlag{ IntSliceFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped IntSliceFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped IntSliceFlag.Apply func (f *IntSliceFlag) Apply(set *flag.FlagSet) { f.set = set f.IntSliceFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped IntSliceFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped IntSliceFlag.ApplyWithError func (f *IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.IntSliceFlag.ApplyWithError(set) @@ -225,18 +224,18 @@ type Int64SliceFlag struct { // NewInt64SliceFlag creates a new Int64SliceFlag func NewInt64SliceFlag(fl cli.Int64SliceFlag) *Int64SliceFlag { - return &Int64SliceFlag{Int64SliceFlag: fl, set: nil} + return &Int64SliceFlag{ Int64SliceFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped Int64SliceFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped Int64SliceFlag.Apply func (f *Int64SliceFlag) Apply(set *flag.FlagSet) { f.set = set f.Int64SliceFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped Int64SliceFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped Int64SliceFlag.ApplyWithError func (f *Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.Int64SliceFlag.ApplyWithError(set) @@ -251,18 +250,18 @@ type StringFlag struct { // NewStringFlag creates a new StringFlag func NewStringFlag(fl cli.StringFlag) *StringFlag { - return &StringFlag{StringFlag: fl, set: nil} + return &StringFlag{ StringFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped StringFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped StringFlag.Apply func (f *StringFlag) Apply(set *flag.FlagSet) { f.set = set f.StringFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped StringFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped StringFlag.ApplyWithError func (f *StringFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.StringFlag.ApplyWithError(set) @@ -277,18 +276,18 @@ type StringSliceFlag struct { // NewStringSliceFlag creates a new StringSliceFlag func NewStringSliceFlag(fl cli.StringSliceFlag) *StringSliceFlag { - return &StringSliceFlag{StringSliceFlag: fl, set: nil} + return &StringSliceFlag{ StringSliceFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped StringSliceFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped StringSliceFlag.Apply func (f *StringSliceFlag) Apply(set *flag.FlagSet) { f.set = set f.StringSliceFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped StringSliceFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped StringSliceFlag.ApplyWithError func (f *StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.StringSliceFlag.ApplyWithError(set) @@ -303,18 +302,18 @@ type Uint64Flag struct { // NewUint64Flag creates a new Uint64Flag func NewUint64Flag(fl cli.Uint64Flag) *Uint64Flag { - return &Uint64Flag{Uint64Flag: fl, set: nil} + return &Uint64Flag{ Uint64Flag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped Uint64Flag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped Uint64Flag.Apply func (f *Uint64Flag) Apply(set *flag.FlagSet) { f.set = set f.Uint64Flag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped Uint64Flag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped Uint64Flag.ApplyWithError func (f *Uint64Flag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.Uint64Flag.ApplyWithError(set) @@ -329,18 +328,18 @@ type UintFlag struct { // NewUintFlag creates a new UintFlag func NewUintFlag(fl cli.UintFlag) *UintFlag { - return &UintFlag{UintFlag: fl, set: nil} + return &UintFlag{ UintFlag: fl, set: nil } } -// Apply saves the flagSet for later usage calls, then calls the -// wrapped UintFlag.Apply +// Apply saves the flagSet for later usage calls, then calls +// the wrapped UintFlag.Apply func (f *UintFlag) Apply(set *flag.FlagSet) { f.set = set f.UintFlag.Apply(set) } -// ApplyWithError saves the flagSet for later usage calls, then calls the -// wrapped UintFlag.ApplyWithError +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped UintFlag.ApplyWithError func (f *UintFlag) ApplyWithError(set *flag.FlagSet) error { f.set = set return f.UintFlag.ApplyWithError(set) diff --git a/appveyor.yml b/appveyor.yml index 1e1489c365..ed7436662a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,19 +8,19 @@ clone_folder: c:\gopath\src\github.com\urfave\cli environment: GOPATH: C:\gopath - GOVERSION: 1.8.x - PYTHON: C:\Python36-x64 - PYTHON_VERSION: 3.6.x - PYTHON_ARCH: 64 + GOVERSION: 1.11.x install: -- set PATH=%GOPATH%\bin;C:\go\bin;%PATH% -- go version -- go env -- go get github.com/urfave/gfmrun/... -- go get -v -t ./... + - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% + - go version + - go env + - go get github.com/shurcooL/vfsgen + - go get github.com/shurcooL/httpfs/union + - go get github.com/urfave/gfmrun/... + - go get -v -t ./... build_script: -- python runtests vet -- python runtests test -- python runtests gfmrun + - go run build.go generate + - go run build.go vet + - go run build.go test + - go run build.go gfmrun diff --git a/build.go b/build.go new file mode 100644 index 0000000000..2a38f8ba82 --- /dev/null +++ b/build.go @@ -0,0 +1,179 @@ +//+build ignore + +package main + +import ( + "bufio" + "bytes" + "fmt" + "github.com/urfave/cli" + "io/ioutil" + "log" + "os" + "os/exec" + "strings" +) + +var packages = []string{"cli", "altsrc"} + +func main() { + app := cli.NewApp() + + app.Name = "builder" + app.Usage = "Generates a new urfave/cli build!" + + app.Commands = cli.Commands{ + cli.Command{ + Name: "vet", + Action: VetActionFunc, + }, + cli.Command{ + Name: "test", + Action: TestActionFunc, + }, + cli.Command{ + Name: "gfmrun", + Action: GfmrunActionFunc, + }, + cli.Command{ + Name: "toc", + Action: TocActionFunc, + }, + cli.Command{ + Name: "generate", + Action: GenActionFunc, + }, + } + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) + } +} + +func VetActionFunc(_ *cli.Context) error { + return exec.Command("go", "vet").Run() +} + +func TestActionFunc(c *cli.Context) error { + for _, pkg := range packages { + var packageName string + + if pkg == "cli" { + packageName = "github.com/urfave/cli" + } else { + packageName = fmt.Sprintf("github.com/urfave/cli/%s", pkg) + } + + coverProfile := fmt.Sprintf("--coverprofile=%s.coverprofile", pkg) + + err := exec.Command( + "go", "test", "-v", coverProfile, packageName, + ).Run() + + if err != nil { + return err + } + } + + return testCleanup() +} + +func testCleanup() error { + var out bytes.Buffer + + for _, pkg := range packages { + file, err := os.Open(fmt.Sprintf("%s.coverprofile", pkg)) + if err != nil { + return err + } + + b, err := ioutil.ReadAll(file) + if err != nil { + return err + } + + out.Write(b) + err = file.Close() + if err != nil { + return err + } + + err = os.Remove(fmt.Sprintf("%s.coverprofile", pkg)) + if err != nil { + return err + } + } + + outFile, err := os.Create("coverage.txt") + if err != nil { + return err + } + + _, err = out.WriteTo(outFile) + if err != nil { + return err + } + + err = outFile.Close() + if err != nil { + return err + } + + return nil +} + +func GfmrunActionFunc(_ *cli.Context) error { + file, err := os.Open("README.md") + if err != nil { + return err + } + + var counter int + scanner := bufio.NewScanner(file) + for scanner.Scan() { + if strings.Contains(scanner.Text(), "package main") { + counter++ + } + } + + err = scanner.Err() + if err != nil { + return err + } + + return exec.Command("gfmrun", "-c", fmt.Sprint(counter), "-s", "README.md").Run() +} + +func TocActionFunc(_ *cli.Context) error { + err := exec.Command("node_modules/.bin/markdown-toc", "-i", "README.md").Run() + if err != nil { + return err + } + + err = exec.Command("git", "diff", "--exit-code").Run() + if err != nil { + return err + } + + return nil +} + +func GenActionFunc(_ *cli.Context) error { + err := exec.Command("go", "generate", "flag-gen/main.go").Run() + if err != nil { + return err + } + + err = exec.Command("go", "generate", "cli.go").Run() + if err != nil { + return err + } + + err = exec.Command("git", "diff", "--exit-code").Run() + if err != nil { + return err + } + + return nil +} diff --git a/cli.go b/cli.go index 90c07eb8ef..4bd2508392 100644 --- a/cli.go +++ b/cli.go @@ -19,4 +19,4 @@ // } package cli -//go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go +//go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go diff --git a/flag-gen/.gitignore b/flag-gen/.gitignore new file mode 100644 index 0000000000..5657f6ea7d --- /dev/null +++ b/flag-gen/.gitignore @@ -0,0 +1 @@ +vendor \ No newline at end of file diff --git a/flag-gen/assets_generate.go b/flag-gen/assets_generate.go new file mode 100644 index 0000000000..021da71918 --- /dev/null +++ b/flag-gen/assets_generate.go @@ -0,0 +1,55 @@ +// +build ignore + +package main + +import ( + "github.com/shurcooL/httpfs/union" + "github.com/shurcooL/vfsgen" + "log" + "net/http" + "os" + "time" +) + +// zeroModTimeFileSystem is an http.FileSystem wrapper. +// It exposes a filesystem exactly like Source, except +// all file modification times are changed to zero. +// See https://github.com/shurcooL/vfsgen/pull/40#issuecomment-355416103 +type zeroModTimeFileSystem struct { + Source http.FileSystem +} + +func (fs zeroModTimeFileSystem) Open(name string) (http.File, error) { + f, err := fs.Source.Open(name) + return file{f}, err +} + +type file struct { + http.File +} + +func (f file) Stat() (os.FileInfo, error) { + fi, err := f.File.Stat() + return fileInfo{fi}, err +} + +type fileInfo struct { + os.FileInfo +} + +func (fi fileInfo) ModTime() time.Time { return time.Time{} } + +func main() { + fs := zeroModTimeFileSystem{ + Source: union.New(map[string]http.FileSystem{ + "/templates": http.Dir("templates"), + "/source": http.Dir("source"), + }), + } + + err := vfsgen.Generate(fs, vfsgen.Options{}) + + if err != nil { + log.Fatal(err) + } +} diff --git a/flag-gen/assets_vfsdata.go b/flag-gen/assets_vfsdata.go new file mode 100644 index 0000000000..024039aa42 --- /dev/null +++ b/flag-gen/assets_vfsdata.go @@ -0,0 +1,214 @@ +// Code generated by vfsgen; DO NOT EDIT. + +package main + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + pathpkg "path" + "time" +) + +// assets statically implements the virtual filesystem provided to vfsgen. +var assets = func() http.FileSystem { + fs := vfsgen۰FS{ + "/": &vfsgen۰DirInfo{ + name: "/", + modTime: time.Time{}, + }, + "/source": &vfsgen۰DirInfo{ + name: "source", + modTime: time.Time{}, + }, + "/source/flag-types.json": &vfsgen۰CompressedFileInfo{ + name: "flag-types.json", + modTime: time.Time{}, + uncompressedSize: 2559, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x94\xc1\x6e\x9c\x30\x10\x86\xef\x3c\xc5\xc8\xbd\x40\xb5\x82\x1c\x56\x7b\xd8\x63\x55\xb5\xda\x5b\xa5\x34\xbd\x24\x51\xe4\x80\x21\x56\x1d\x1b\xd9\x43\xd4\x28\xca\xbb\x57\xf6\x2e\xbb\x60\x0c\x62\x5b\x2d\xb9\xfe\x23\x98\xef\x9b\xb1\xe6\x36\x02\x78\x8b\x00\x00\x88\xa4\xcf\x8c\x6c\x81\x7c\x51\x4a\x90\xd5\x3e\xc3\xd7\xda\x65\x8f\x9d\xec\x85\x8a\xc6\x86\x25\x15\x86\x1d\xb2\x82\x19\x24\x5b\x40\xdd\xb4\x49\xae\x24\xb2\x3f\xf8\x50\xb0\x92\x36\xc2\x16\x89\xfb\xa0\xfd\x4b\x4d\xb5\x61\xda\xc6\x06\x75\xae\xe4\x4b\xfa\xc3\x26\xb6\x79\x5c\xa6\xbf\x6c\x8f\xf4\x1a\x35\x97\x55\x9c\x24\x24\x02\x78\x5f\x85\x51\x7f\xfe\x3f\x6b\xa1\x72\xa4\x5c\xd8\x8f\x01\x9f\x28\x02\x37\xae\x0c\x8f\xaf\xd0\xf2\x2f\xa9\xf5\xb5\xd1\x14\xb9\x92\xbe\x19\xf2\x67\x96\xfa\xc5\x56\xb1\xeb\x33\x69\x18\x1b\xc6\xe0\x09\xb1\x36\xdb\x2c\xab\x94\xa0\xb2\x4a\x95\xae\xb2\xfa\x77\x95\xd9\x0e\xd9\x27\x87\xdc\xf6\x49\x26\xd4\xaf\x86\xda\x8e\xb1\xf7\x83\xf9\xde\xdf\x84\xa2\xb8\x59\xfb\xda\x65\x3f\x9e\x25\x3c\x0f\xb6\xb7\x23\xd7\x7d\x00\xbb\x82\xcd\x7a\x14\xf8\x3b\x93\x4c\xf3\xdc\x07\xf6\xe2\x71\xe0\xee\xb3\x0c\x10\x4b\x2e\xfc\xe1\xb7\x2d\xb8\x44\xa6\x4b\x9a\xb3\xb7\xf7\x31\xb8\x9d\x0c\xcc\x92\xcb\x05\x26\xb9\x93\xa1\x39\x5e\x4d\x8e\x72\x27\x31\xc0\xfa\xa1\xa4\xbd\x4f\x1f\x72\xea\xfa\x59\xaa\xd8\x45\xc5\x94\xcb\xb5\xe0\x39\xf3\x85\x3e\xfb\x85\x4b\xbc\x8c\xdb\xfb\xce\xdc\x4e\xda\x47\xcd\xf8\x48\x91\x24\xfb\xc8\x2a\x33\xad\x95\x8e\x25\x17\x53\x52\x9b\xf5\xa8\x96\x57\xba\x98\xd8\xe9\xf1\x8e\xa9\x1d\x48\xce\x93\xdb\xef\xde\x17\x33\xbd\xf4\x5f\xdf\xe0\x1d\xb9\x23\x43\xe8\xe1\xab\x9b\x4b\x19\xde\x41\xa0\x76\x99\x25\xf4\x87\x12\xdc\x42\x87\xe5\xbc\x35\xdc\xf0\xd0\xcd\x6a\x16\x39\x5a\xb6\xf7\xd9\x57\xeb\x86\x0f\xcf\x56\xb3\xc0\xdd\x9a\x86\x0d\x1f\xae\xc6\xbf\x5c\xd1\x7d\xf4\x37\x00\x00\xff\xff\x66\x52\x85\x44\xff\x09\x00\x00"), + }, + "/templates": &vfsgen۰DirInfo{ + name: "templates", + modTime: time.Time{}, + }, + "/templates/altsrc_flags_generated.gotpl": &vfsgen۰CompressedFileInfo{ + name: "altsrc_flags_generated.gotpl", + modTime: time.Time{}, + uncompressedSize: 1044, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x92\x4f\x8b\xdb\x30\x10\xc5\xcf\xd6\xa7\x78\x84\xa5\xc4\x4b\xb0\xef\x29\x7b\x28\xdd\x2d\xf4\x92\x2d\xec\x42\xcf\x8a\x3c\xb2\x45\x15\xdb\x48\xe3\x84\x20\xfc\xdd\xcb\x38\x61\xfb\x4f\x29\xbd\xf4\x66\x69\xf4\xde\x9b\xdf\x8c\xeb\x1a\x1f\x87\x86\xd0\x52\x4f\x41\x33\x35\xd8\x9f\x61\xdb\xf7\x78\x7c\xc6\xee\xf9\x15\x4f\x8f\x9f\x5f\x2b\xa5\x46\x6d\xbe\xe9\x96\x90\x12\xaa\x2f\x97\xef\x9d\x3e\x10\xe6\x59\x29\x77\x18\x87\xc0\x58\xab\x62\x65\xbd\x6e\x57\xaa\x58\xb5\x8e\xbb\x69\x5f\x99\xe1\x50\x4f\xc1\xea\x23\xd5\xc6\xbb\x95\x2a\x55\x4a\x08\xba\x6f\x09\x77\x6e\x83\x3b\x79\x8e\xed\x03\xaa\x4f\x5e\xb7\x51\xcc\xea\x5a\x22\x96\x42\x75\x0d\x90\x1a\x5c\x04\x77\x84\x45\xc0\xe7\x91\xc0\x9d\x66\x9c\x82\x1e\x23\x8c\x77\x55\x56\xc4\x03\xb4\xf7\xc3\x49\x5c\xed\x10\x30\x70\x47\x01\x47\xed\x27\x8a\x52\xdc\x13\xe2\x48\xc6\x59\x47\x8d\x5a\x5c\xb3\x36\x91\xc3\x64\x18\x49\x15\xb7\x92\x54\x11\x89\x71\xbf\x5c\xcb\xf9\x85\x58\xcd\x4a\x62\x77\x74\xca\x7a\x9a\x40\x9a\x29\x42\xa3\xa7\x53\x36\x56\xd9\xa9\x37\xb7\xf4\x6b\xeb\x6f\x62\x97\xb8\xcf\x46\x26\x55\x04\xe2\x29\xf4\x78\x97\xab\xa7\x6c\x17\x5b\x58\xbf\x41\x24\xde\xa2\x77\x1e\xf3\x15\xeb\xc3\x38\xfa\x33\xa2\x3e\xd2\x8f\xbd\xbc\x10\x2f\x53\xf6\x9a\x29\x60\x8a\xf2\xbb\x18\xed\x7d\xdc\xc8\x93\xfe\xf2\x2d\x62\x11\xc8\xe6\x46\x6a\xb2\x99\xd5\xe2\x7e\xe1\x5f\xdb\x3c\x4d\x79\x69\x61\xfd\xc7\xdc\x4b\xe1\xb4\x95\xdc\x3f\x48\xdf\x72\xb8\x1d\x22\xfa\xf2\x67\xa6\xaf\x8e\xbb\xa7\x10\x86\xf0\x7f\xe1\xde\x62\xfe\x89\xf2\xed\x75\x0e\x97\x96\x6e\x7f\x87\xbe\x6e\xfa\x6f\xec\xbf\xb8\xca\x10\x52\x02\xf5\x0d\xe6\xf9\x7b\x00\x00\x00\xff\xff\x6d\x3d\x9e\xe0\x14\x04\x00\x00"), + }, + "/templates/cli_flags_generated.gotpl": &vfsgen۰CompressedFileInfo{ + name: "cli_flags_generated.gotpl", + modTime: time.Time{}, + uncompressedSize: 2102, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\xc1\x52\xdb\x30\x10\x3d\xdb\x5f\xb1\xcd\x70\xb0\x99\x34\xb9\x97\xe1\x44\xa0\x65\xa6\x03\x4c\xa1\xdc\x15\x7b\xe5\x68\x10\x52\x90\xd6\x50\x26\x93\x7f\xef\xac\x24\x3b\x4e\x48\x21\x17\x7a\xd3\x6a\x9f\xde\x7b\x7a\x5a\x7b\x3a\x85\x33\x5b\x23\x34\x68\xd0\x09\xc2\x1a\xe6\xaf\x20\x9b\x13\x98\x5d\xc3\xd5\xf5\x1d\x9c\xcf\x2e\xef\x26\x79\xbe\x14\xd5\x83\x68\x10\x56\x2b\x98\xdc\xc4\xf5\x95\x78\x44\x58\xaf\xf3\x5c\x3d\x2e\xad\x23\x28\xf2\x6c\x24\xb5\x68\x46\x79\x36\xf2\xe4\x2a\x6b\x9e\x79\x49\xea\x11\x47\x79\x99\xaf\x56\xe0\x84\x69\x10\x8e\xd4\x18\x8e\x18\x08\xdf\x4e\x61\x72\xa1\x45\xe3\x99\x66\x3a\x65\xf2\xd0\x98\x24\x6a\xee\x81\xf2\x20\x20\xc0\x5f\x14\x2d\x80\x5e\x97\xb8\x01\xde\x71\xb5\x5e\xf7\xf5\xcc\x56\x24\x94\x66\xbe\x6d\xe0\x90\xd1\x93\x6b\x2b\x82\x55\x9e\xf1\x6e\x96\x79\x72\xca\x34\x79\xf6\xdb\x8b\x66\x50\x9e\x9b\xe7\x7b\xe1\x36\xf5\x85\xd2\x78\x23\x68\xd1\x6f\xfc\xc2\xa7\x56\x39\xac\xb3\xb9\xb5\x3a\xcf\x7e\xa8\xba\x46\x93\xa5\x6a\xb5\xfa\x0a\x4a\x02\x3e\x25\x03\xf7\x42\xb7\x08\xe4\xda\x90\x59\x16\xca\x6c\xf7\x1e\xf1\x18\x9a\xba\x5f\x0f\x29\x66\xe8\x49\x19\x41\xca\x9a\x0d\xd1\x60\x33\x3b\x7e\x97\x6f\x9d\x73\xc6\xb7\xc1\x3c\x38\xa4\xd6\x19\x8e\xd6\xa1\xa8\xc5\x5c\x23\x38\x5c\x3a\xf4\x68\x28\x2a\x58\x09\xb4\x50\x1e\x9e\xd9\x29\x9f\x2c\xa4\x75\xd0\x72\x46\x50\xa3\x14\xad\x26\x5f\xe6\xb2\x35\x15\x14\x72\x6f\xd0\x65\x12\x2b\x4a\x88\x91\x71\xe4\x51\x18\xb8\x1f\xbb\xe8\x0a\x59\x26\x73\xdf\x91\xc2\xf9\xce\x1d\x2d\x10\x0c\x6f\x04\x33\x18\xc6\xe0\x03\xc9\x44\xb1\x4f\x53\x06\x64\x92\xba\xf4\xdd\xf3\xf5\x6a\x2f\x0b\xa4\x05\x3a\xb0\x0e\x8c\xa5\x5e\x90\x27\xd0\x25\xec\x07\xe2\x1b\xd2\xa2\x04\x9e\x83\x2d\xf5\xae\x97\x1c\xec\x52\x80\xb6\xf6\xc1\x43\xbb\x0c\xca\x21\x76\xbe\xb7\x00\x6d\x2b\xa1\xf7\x2a\x8e\x3b\xef\x5b\x7c\x67\xd6\x10\xfe\xa1\x59\x7c\x24\x66\x56\x32\xdc\x48\xda\xd6\x74\x57\xa8\xe0\x38\xe1\xca\x37\xd4\x45\xc8\x3c\xe6\x17\xba\x7c\x1e\xa1\x23\x0e\xc3\x35\x1a\x0d\xbf\xbb\x61\x27\x6c\xa3\xf6\x5b\x1f\x66\xdf\xe9\xc6\x71\x90\x0c\xdf\xbb\x5d\xee\x35\x31\x86\x6a\xc2\x9b\xb7\x48\xfd\x8c\x68\x3b\x17\xfa\xe0\xf0\x9a\x00\xff\xcc\xf4\xf6\x1b\xfa\x5f\x19\x2a\x09\xd2\xf3\x9f\x34\xa6\x18\xcd\x5c\xc4\xc8\xba\x08\xcb\x13\xc6\x7c\x39\x05\xa3\xc2\x44\x1e\x14\xbc\xf4\x65\x9e\xad\xfb\x47\xfa\x77\x3e\xfc\x2e\x21\x95\x77\xe8\x52\x10\x63\xf0\x48\x70\x1c\xda\xc9\xe3\x67\x66\x23\x39\x17\x8f\x34\xf9\x19\x9c\x05\x27\x65\x8c\x6c\x98\xc6\xc6\xc0\x8d\x70\x1e\x5d\xd4\x5e\xf2\xba\x1e\x03\x3a\xc7\x34\xbd\x52\xc2\x0c\x5d\xec\x40\x65\xfc\xd9\x87\xda\xba\xc2\x28\x5d\x32\x36\xfd\xd5\x59\x9e\x81\x03\x03\x07\x64\x9c\xf1\x53\xbc\x71\x7a\x26\x3c\x45\xb7\xbb\x0c\x83\xfe\xd0\x69\x82\x45\xc3\x03\x53\x07\xbe\x73\x7f\xe2\x6f\x00\x00\x00\xff\xff\x9b\xde\x9c\x04\x36\x08\x00\x00"), + }, + } + fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ + fs["/source"].(os.FileInfo), + fs["/templates"].(os.FileInfo), + } + fs["/source"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ + fs["/source/flag-types.json"].(os.FileInfo), + } + fs["/templates"].(*vfsgen۰DirInfo).entries = []os.FileInfo{ + fs["/templates/altsrc_flags_generated.gotpl"].(os.FileInfo), + fs["/templates/cli_flags_generated.gotpl"].(os.FileInfo), + } + + return fs +}() + +type vfsgen۰FS map[string]interface{} + +func (fs vfsgen۰FS) Open(path string) (http.File, error) { + path = pathpkg.Clean("/" + path) + f, ok := fs[path] + if !ok { + return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist} + } + + switch f := f.(type) { + case *vfsgen۰CompressedFileInfo: + gr, err := gzip.NewReader(bytes.NewReader(f.compressedContent)) + if err != nil { + // This should never happen because we generate the gzip bytes such that they are always valid. + panic("unexpected error reading own gzip compressed bytes: " + err.Error()) + } + return &vfsgen۰CompressedFile{ + vfsgen۰CompressedFileInfo: f, + gr: gr, + }, nil + case *vfsgen۰DirInfo: + return &vfsgen۰Dir{ + vfsgen۰DirInfo: f, + }, nil + default: + // This should never happen because we generate only the above types. + panic(fmt.Sprintf("unexpected type %T", f)) + } +} + +// vfsgen۰CompressedFileInfo is a static definition of a gzip compressed file. +type vfsgen۰CompressedFileInfo struct { + name string + modTime time.Time + compressedContent []byte + uncompressedSize int64 +} + +func (f *vfsgen۰CompressedFileInfo) Readdir(count int) ([]os.FileInfo, error) { + return nil, fmt.Errorf("cannot Readdir from file %s", f.name) +} +func (f *vfsgen۰CompressedFileInfo) Stat() (os.FileInfo, error) { return f, nil } + +func (f *vfsgen۰CompressedFileInfo) GzipBytes() []byte { + return f.compressedContent +} + +func (f *vfsgen۰CompressedFileInfo) Name() string { return f.name } +func (f *vfsgen۰CompressedFileInfo) Size() int64 { return f.uncompressedSize } +func (f *vfsgen۰CompressedFileInfo) Mode() os.FileMode { return 0444 } +func (f *vfsgen۰CompressedFileInfo) ModTime() time.Time { return f.modTime } +func (f *vfsgen۰CompressedFileInfo) IsDir() bool { return false } +func (f *vfsgen۰CompressedFileInfo) Sys() interface{} { return nil } + +// vfsgen۰CompressedFile is an opened compressedFile instance. +type vfsgen۰CompressedFile struct { + *vfsgen۰CompressedFileInfo + gr *gzip.Reader + grPos int64 // Actual gr uncompressed position. + seekPos int64 // Seek uncompressed position. +} + +func (f *vfsgen۰CompressedFile) Read(p []byte) (n int, err error) { + if f.grPos > f.seekPos { + // Rewind to beginning. + err = f.gr.Reset(bytes.NewReader(f.compressedContent)) + if err != nil { + return 0, err + } + f.grPos = 0 + } + if f.grPos < f.seekPos { + // Fast-forward. + _, err = io.CopyN(ioutil.Discard, f.gr, f.seekPos-f.grPos) + if err != nil { + return 0, err + } + f.grPos = f.seekPos + } + n, err = f.gr.Read(p) + f.grPos += int64(n) + f.seekPos = f.grPos + return n, err +} +func (f *vfsgen۰CompressedFile) Seek(offset int64, whence int) (int64, error) { + switch whence { + case io.SeekStart: + f.seekPos = 0 + offset + case io.SeekCurrent: + f.seekPos += offset + case io.SeekEnd: + f.seekPos = f.uncompressedSize + offset + default: + panic(fmt.Errorf("invalid whence value: %v", whence)) + } + return f.seekPos, nil +} +func (f *vfsgen۰CompressedFile) Close() error { + return f.gr.Close() +} + +// vfsgen۰DirInfo is a static definition of a directory. +type vfsgen۰DirInfo struct { + name string + modTime time.Time + entries []os.FileInfo +} + +func (d *vfsgen۰DirInfo) Read([]byte) (int, error) { + return 0, fmt.Errorf("cannot Read from directory %s", d.name) +} +func (d *vfsgen۰DirInfo) Close() error { return nil } +func (d *vfsgen۰DirInfo) Stat() (os.FileInfo, error) { return d, nil } + +func (d *vfsgen۰DirInfo) Name() string { return d.name } +func (d *vfsgen۰DirInfo) Size() int64 { return 0 } +func (d *vfsgen۰DirInfo) Mode() os.FileMode { return 0755 | os.ModeDir } +func (d *vfsgen۰DirInfo) ModTime() time.Time { return d.modTime } +func (d *vfsgen۰DirInfo) IsDir() bool { return true } +func (d *vfsgen۰DirInfo) Sys() interface{} { return nil } + +// vfsgen۰Dir is an opened dir instance. +type vfsgen۰Dir struct { + *vfsgen۰DirInfo + pos int // Position within entries for Seek and Readdir. +} + +func (d *vfsgen۰Dir) Seek(offset int64, whence int) (int64, error) { + if offset == 0 && whence == io.SeekStart { + d.pos = 0 + return 0, nil + } + return 0, fmt.Errorf("unsupported Seek in directory %s", d.name) +} + +func (d *vfsgen۰Dir) Readdir(count int) ([]os.FileInfo, error) { + if d.pos >= len(d.entries) && count > 0 { + return nil, io.EOF + } + if count <= 0 || count > len(d.entries)-d.pos { + count = len(d.entries) - d.pos + } + e := d.entries[d.pos : d.pos+count] + d.pos += count + return e, nil +} diff --git a/flag-gen/go.mod b/flag-gen/go.mod new file mode 100644 index 0000000000..c93d180b68 --- /dev/null +++ b/flag-gen/go.mod @@ -0,0 +1,9 @@ +module github.com/urfave/cli/flag-generator + +go 1.12 + +require ( + github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 + github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd + github.com/urfave/cli v1.21.0 +) diff --git a/flag-gen/go.sum b/flag-gen/go.sum new file mode 100644 index 0000000000..e68bf88b1e --- /dev/null +++ b/flag-gen/go.sum @@ -0,0 +1,9 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE= +github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/flag-gen/main.go b/flag-gen/main.go new file mode 100644 index 0000000000..9caa94e7f4 --- /dev/null +++ b/flag-gen/main.go @@ -0,0 +1,113 @@ +package main + +//go:generate go run assets_generate.go + +import ( + "encoding/json" + "fmt" + "github.com/urfave/cli" + "io/ioutil" + "log" + "os" + "text/template" +) + +type CliFlagInfo struct { + PackageName string + Flags []FlagType +} + +type FlagType struct { + Name string `json:"name"` + Type string `json:"type"` + Value bool `json:"value"` + Destination bool `json:"dest"` + Doctail string `json:"doctail"` + ContextDefault string `json:"context_default"` + ContextType string `json:"context_type"` + Parser string `json:"parser"` + ParserCast string `json:"parser_cast"` +} + +func main() { + app := cli.NewApp() + + app.Name = "flag-generator" + app.Usage = "Generate flag type code!" + + app.Action = ActionFunc + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) + } +} + +func ActionFunc(_ *cli.Context) error { + var info CliFlagInfo + var tpl *template.Template + + inFile, err := assets.Open("/source/flag-types.json") + if err != nil { + log.Fatal(err) + } + + decoder := json.NewDecoder(inFile) + err = decoder.Decode(&info.Flags) + if err != nil { + log.Fatal(err) + } + + err = inFile.Close() + if err != nil { + log.Fatal(err) + } + + for _, packageName := range []string{"cli", "altsrc"} { + info.PackageName = packageName + + bytes, err := ReadTemplate(packageName) + if err != nil { + log.Fatal(err) + } + + tpl = template.Must(template.New("").Parse(string(bytes))) + + var outFile *os.File + + if packageName == "cli" { + outFile, err = os.Create("flag_generated.go") + } else { + outFile, err = os.Create("altsrc/flag_generated.go") + } + if err != nil { + log.Fatal(err) + } + + err = tpl.Execute(outFile, info) + if err != nil { + log.Fatal(err) + } + + err = outFile.Close() + if err != nil { + log.Fatal(err) + } + } + + return nil +} + +func ReadTemplate(packageName string) ([]byte, error) { + templateFile, err := assets.Open(fmt.Sprintf("/templates/%s_flags_generated.gotpl", packageName)) + if err != nil { + return nil, err + } + + templateFileBytes, err := ioutil.ReadAll(templateFile) + if err != nil { + return nil, err + } + + return templateFileBytes, nil +} diff --git a/flag-types.json b/flag-gen/source/flag-types.json similarity index 85% rename from flag-types.json rename to flag-gen/source/flag-types.json index 1223107859..3306025075 100644 --- a/flag-types.json +++ b/flag-gen/source/flag-types.json @@ -3,6 +3,7 @@ "name": "Bool", "type": "bool", "value": false, + "dest": true, "context_default": "false", "parser": "strconv.ParseBool(f.Value.String())" }, @@ -10,6 +11,7 @@ "name": "BoolT", "type": "bool", "value": false, + "dest": true, "doctail": " that is true by default", "context_default": "false", "parser": "strconv.ParseBool(f.Value.String())" @@ -17,6 +19,8 @@ { "name": "Duration", "type": "time.Duration", + "value": true, + "dest": true, "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", "context_default": "0", "parser": "time.ParseDuration(f.Value.String())" @@ -24,12 +28,15 @@ { "name": "Float64", "type": "float64", + "value": true, + "dest": true, "context_default": "0", "parser": "strconv.ParseFloat(f.Value.String(), 64)" }, { "name": "Generic", "type": "Generic", + "value": true, "dest": false, "context_default": "nil", "context_type": "interface{}" @@ -37,12 +44,16 @@ { "name": "Int64", "type": "int64", + "value": true, + "dest": true, "context_default": "0", "parser": "strconv.ParseInt(f.Value.String(), 0, 64)" }, { "name": "Int", "type": "int", + "value": true, + "dest": true, "context_default": "0", "parser": "strconv.ParseInt(f.Value.String(), 0, 64)", "parser_cast": "int(parsed)" @@ -50,6 +61,7 @@ { "name": "IntSlice", "type": "*IntSlice", + "value": true, "dest": false, "context_default": "nil", "context_type": "[]int", @@ -58,6 +70,7 @@ { "name": "Int64Slice", "type": "*Int64Slice", + "value": true, "dest": false, "context_default": "nil", "context_type": "[]int64", @@ -66,12 +79,15 @@ { "name": "String", "type": "string", + "value": true, + "dest": true, "context_default": "\"\"", "parser": "f.Value.String(), error(nil)" }, { "name": "StringSlice", "type": "*StringSlice", + "value": true, "dest": false, "context_default": "nil", "context_type": "[]string", @@ -80,12 +96,16 @@ { "name": "Uint64", "type": "uint64", + "value": true, + "dest": true, "context_default": "0", "parser": "strconv.ParseUint(f.Value.String(), 0, 64)" }, { "name": "Uint", "type": "uint", + "value": true, + "dest": true, "context_default": "0", "parser": "strconv.ParseUint(f.Value.String(), 0, 64)", "parser_cast": "uint(parsed)" diff --git a/flag-gen/templates/altsrc_flags_generated.gotpl b/flag-gen/templates/altsrc_flags_generated.gotpl new file mode 100644 index 0000000000..07f6e82d77 --- /dev/null +++ b/flag-gen/templates/altsrc_flags_generated.gotpl @@ -0,0 +1,35 @@ +// Code generated by fg; DO NOT EDIT. + +package {{ .PackageName }} + +import ( + "flag" + "github.com/urfave/cli" +) +{{ range $i, $flag := .Flags }} +// {{ $flag.Name }}Flag is the flag type that wraps cli.{{ $flag.Name }}Flag to allow +// for other values to be specified +type {{ $flag.Name }}Flag struct { + cli.{{ $flag.Name }}Flag + set *flag.FlagSet +} + +// New{{ $flag.Name }}Flag creates a new {{ $flag.Name }}Flag +func New{{ $flag.Name }}Flag(fl cli.{{ $flag.Name }}Flag) *{{ $flag.Name }}Flag { + return &{{ $flag.Name }}Flag{ {{ $flag.Name }}Flag: fl, set: nil } +} + +// Apply saves the flagSet for later usage calls, then calls +// the wrapped {{ $flag.Name }}Flag.Apply +func (f *{{ $flag.Name }}Flag) Apply(set *flag.FlagSet) { + f.set = set + f.{{ $flag.Name }}Flag.Apply(set) +} + +// ApplyWithError saves the flagSet for later usage calls, then calls +// the wrapped {{ $flag.Name }}Flag.ApplyWithError +func (f *{{ $flag.Name }}Flag) ApplyWithError(set *flag.FlagSet) error { + f.set = set + return f.{{ $flag.Name }}Flag.ApplyWithError(set) +} +{{ end }} \ No newline at end of file diff --git a/flag-gen/templates/cli_flags_generated.gotpl b/flag-gen/templates/cli_flags_generated.gotpl new file mode 100644 index 0000000000..97bd49fab9 --- /dev/null +++ b/flag-gen/templates/cli_flags_generated.gotpl @@ -0,0 +1,69 @@ +// Code generated by fg; DO NOT EDIT. + +package {{ .PackageName }} + +import ( + "flag" + "strconv" + "time" +) +{{ range $i, $flag := .Flags }} +// {{ $flag.Name }}Flag is a flag with type {{ $flag.Type }}{{ $flag.Doctail }} +type {{ $flag.Name }}Flag struct { + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + {{- if eq $flag.Value true }} + Value {{ $flag.Type }} + {{- end }} + {{- if eq $flag.Destination true }} + Destination *{{ $flag.Type }} + {{- end }} +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f {{ $flag.Name }}Flag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f {{ $flag.Name }}Flag) GetName() string { + return f.Name +} + +// IsRequired returns whether or not the flag is required +func (f {{ $flag.Name }}Flag) IsRequired() bool { + return f.Required +} + +// {{ $flag.Name }} looks up the value of a local {{ $flag.Name }}Flag, returns +// {{ $flag.ContextDefault }} if not found +func (c *Context) {{ $flag.Name }}(name string) {{ if ne .ContextType "" }}{{ $flag.ContextType }}{{ else }}{{ $flag.Type }}{{- end }} { + return lookup{{ $flag.Name }}(name, c.flagSet) +} + +// Global{{ $flag.Name }} looks up the value of a global {{ $flag.Name }}Flag, returns +// {{ $flag.ContextDefault }} if not found +func (c *Context) Global{{ $flag.Name }}(name string) {{ if ne .ContextType "" }}{{ $flag.ContextType }}{{ else }}{{ $flag.Type }}{{- end }} { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookup{{ $flag.Name }}(name, fs) + } + return {{ $flag.ContextDefault }} +} + +func lookup{{ $flag.Name }}(name string, set *flag.FlagSet) {{ if ne .ContextType "" }}{{ $flag.ContextType }}{{ else }}{{ $flag.Type }}{{- end }} { + f := set.Lookup(name) + if f != nil { + {{ if ne .Parser "" }}parsed, err := {{ $flag.Parser }}{{ else }}parsed, err := f.Value, error(nil){{ end }} + if err != nil { + return {{ $flag.ContextDefault }} + } + {{ if ne .ParserCast "" }}return {{ $flag.ParserCast }}{{ else }}return parsed{{ end }} + } + return {{ $flag.ContextDefault }} +} +{{ end }} \ No newline at end of file diff --git a/flag_generated.go b/flag_generated.go index a3e4d6e9d5..83e10d7988 100644 --- a/flag_generated.go +++ b/flag_generated.go @@ -1,3 +1,5 @@ +// Code generated by fg; DO NOT EDIT. + package cli import ( @@ -6,17 +8,15 @@ import ( "time" ) -// WARNING: This file is generated! - // BoolFlag is a flag with type bool type BoolFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Destination *bool + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Destination *bool } // String returns a readable representation of this value @@ -30,7 +30,7 @@ func (f BoolFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f BoolFlag) IsRequired() bool { return f.Required } @@ -64,13 +64,13 @@ func lookupBool(name string, set *flag.FlagSet) bool { // BoolTFlag is a flag with type bool that is true by default type BoolTFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Destination *bool + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Destination *bool } // String returns a readable representation of this value @@ -84,7 +84,7 @@ func (f BoolTFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f BoolTFlag) IsRequired() bool { return f.Required } @@ -118,14 +118,14 @@ func lookupBoolT(name string, set *flag.FlagSet) bool { // DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) type DurationFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value time.Duration - Destination *time.Duration + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value time.Duration + Destination *time.Duration } // String returns a readable representation of this value @@ -139,7 +139,7 @@ func (f DurationFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f DurationFlag) IsRequired() bool { return f.Required } @@ -173,14 +173,14 @@ func lookupDuration(name string, set *flag.FlagSet) time.Duration { // Float64Flag is a flag with type float64 type Float64Flag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value float64 - Destination *float64 + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value float64 + Destination *float64 } // String returns a readable representation of this value @@ -194,7 +194,7 @@ func (f Float64Flag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f Float64Flag) IsRequired() bool { return f.Required } @@ -228,13 +228,13 @@ func lookupFloat64(name string, set *flag.FlagSet) float64 { // GenericFlag is a flag with type Generic type GenericFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value Generic + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value Generic } // String returns a readable representation of this value @@ -248,7 +248,7 @@ func (f GenericFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f GenericFlag) IsRequired() bool { return f.Required } @@ -282,14 +282,14 @@ func lookupGeneric(name string, set *flag.FlagSet) interface{} { // Int64Flag is a flag with type int64 type Int64Flag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value int64 - Destination *int64 + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value int64 + Destination *int64 } // String returns a readable representation of this value @@ -303,7 +303,7 @@ func (f Int64Flag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f Int64Flag) IsRequired() bool { return f.Required } @@ -337,14 +337,14 @@ func lookupInt64(name string, set *flag.FlagSet) int64 { // IntFlag is a flag with type int type IntFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value int - Destination *int + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value int + Destination *int } // String returns a readable representation of this value @@ -358,7 +358,7 @@ func (f IntFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f IntFlag) IsRequired() bool { return f.Required } @@ -392,13 +392,13 @@ func lookupInt(name string, set *flag.FlagSet) int { // IntSliceFlag is a flag with type *IntSlice type IntSliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value *IntSlice + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value *IntSlice } // String returns a readable representation of this value @@ -412,7 +412,7 @@ func (f IntSliceFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f IntSliceFlag) IsRequired() bool { return f.Required } @@ -446,13 +446,13 @@ func lookupIntSlice(name string, set *flag.FlagSet) []int { // Int64SliceFlag is a flag with type *Int64Slice type Int64SliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value *Int64Slice + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value *Int64Slice } // String returns a readable representation of this value @@ -466,7 +466,7 @@ func (f Int64SliceFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f Int64SliceFlag) IsRequired() bool { return f.Required } @@ -500,14 +500,14 @@ func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { // StringFlag is a flag with type string type StringFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value string - Destination *string + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value string + Destination *string } // String returns a readable representation of this value @@ -521,7 +521,7 @@ func (f StringFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f StringFlag) IsRequired() bool { return f.Required } @@ -555,13 +555,13 @@ func lookupString(name string, set *flag.FlagSet) string { // StringSliceFlag is a flag with type *StringSlice type StringSliceFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value *StringSlice + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value *StringSlice } // String returns a readable representation of this value @@ -575,7 +575,7 @@ func (f StringSliceFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f StringSliceFlag) IsRequired() bool { return f.Required } @@ -609,14 +609,14 @@ func lookupStringSlice(name string, set *flag.FlagSet) []string { // Uint64Flag is a flag with type uint64 type Uint64Flag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value uint64 - Destination *uint64 + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value uint64 + Destination *uint64 } // String returns a readable representation of this value @@ -630,7 +630,7 @@ func (f Uint64Flag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f Uint64Flag) IsRequired() bool { return f.Required } @@ -664,14 +664,14 @@ func lookupUint64(name string, set *flag.FlagSet) uint64 { // UintFlag is a flag with type uint type UintFlag struct { - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - Value uint - Destination *uint + Name string + Usage string + EnvVar string + FilePath string + Required bool + Hidden bool + Value uint + Destination *uint } // String returns a readable representation of this value @@ -685,7 +685,7 @@ func (f UintFlag) GetName() string { return f.Name } -// IsRequired returns the whether or not the flag is required +// IsRequired returns whether or not the flag is required func (f UintFlag) IsRequired() bool { return f.Required } diff --git a/generate-flag-types b/generate-flag-types deleted file mode 100755 index e0b5aa15b6..0000000000 --- a/generate-flag-types +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python -""" -The flag types that ship with the cli library have many things in common, and -so we can take advantage of the `go generate` command to create much of the -source code from a list of definitions. These definitions attempt to cover -the parts that vary between flag types, and should evolve as needed. - -An example of the minimum definition needed is: - - { - "name": "SomeType", - "type": "sometype", - "context_default": "nil" - } - -In this example, the code generated for the `cli` package will include a type -named `SomeTypeFlag` that is expected to wrap a value of type `sometype`. -Fetching values by name via `*cli.Context` will default to a value of `nil`. - -A more complete, albeit somewhat redundant, example showing all available -definition keys is: - - { - "name": "VeryMuchType", - "type": "*VeryMuchType", - "value": true, - "dest": false, - "doctail": " which really only wraps a []float64, oh well!", - "context_type": "[]float64", - "context_default": "nil", - "parser": "parseVeryMuchType(f.Value.String())", - "parser_cast": "[]float64(parsed)" - } - -The meaning of each field is as follows: - - name (string) - The type "name", which will be suffixed with - `Flag` when generating the type definition - for `cli` and the wrapper type for `altsrc` - type (string) - The type that the generated `Flag` type for `cli` - is expected to "contain" as its `.Value` member - value (bool) - Should the generated `cli` type have a `Value` - member? - dest (bool) - Should the generated `cli` type support a - destination pointer? - doctail (string) - Additional docs for the `cli` flag type comment - context_type (string) - The literal type used in the `*cli.Context` - reader func signature - context_default (string) - The literal value used as the default by the - `*cli.Context` reader funcs when no value is - present - parser (string) - Literal code used to parse the flag `f`, - expected to have a return signature of - (value, error) - parser_cast (string) - Literal code used to cast the `parsed` value - returned from the `parser` code -""" - -from __future__ import print_function, unicode_literals - -import argparse -import json -import os -import subprocess -import sys -import tempfile -import textwrap - - -class _FancyFormatter(argparse.ArgumentDefaultsHelpFormatter, - argparse.RawDescriptionHelpFormatter): - pass - - -def main(sysargs=sys.argv[:]): - parser = argparse.ArgumentParser( - description='Generate flag type code!', - formatter_class=_FancyFormatter) - parser.add_argument( - 'package', - type=str, default='cli', choices=_WRITEFUNCS.keys(), - help='Package for which flag types will be generated' - ) - parser.add_argument( - '-i', '--in-json', - type=argparse.FileType('r'), - default=sys.stdin, - help='Input JSON file which defines each type to be generated' - ) - parser.add_argument( - '-o', '--out-go', - type=argparse.FileType('w'), - default=sys.stdout, - help='Output file/stream to which generated source will be written' - ) - parser.epilog = __doc__ - - args = parser.parse_args(sysargs[1:]) - _generate_flag_types(_WRITEFUNCS[args.package], args.out_go, args.in_json) - return 0 - - -def _generate_flag_types(writefunc, output_go, input_json): - types = json.load(input_json) - - tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False) - writefunc(tmp, types) - tmp.close() - - new_content = subprocess.check_output( - ['goimports', tmp.name] - ).decode('utf-8') - - print(new_content, file=output_go, end='') - output_go.flush() - os.remove(tmp.name) - - -def _set_typedef_defaults(typedef): - typedef.setdefault('doctail', '') - typedef.setdefault('context_type', typedef['type']) - typedef.setdefault('dest', True) - typedef.setdefault('value', True) - typedef.setdefault('parser', 'f.Value, error(nil)') - typedef.setdefault('parser_cast', 'parsed') - - -def _write_cli_flag_types(outfile, types): - _fwrite(outfile, """\ - package cli - - // WARNING: This file is generated! - - """) - - for typedef in types: - _set_typedef_defaults(typedef) - - _fwrite(outfile, """\ - // {name}Flag is a flag with type {type}{doctail} - type {name}Flag struct {{ - Name string - Usage string - EnvVar string - FilePath string - Required bool - Hidden bool - """.format(**typedef)) - - if typedef['value']: - _fwrite(outfile, """\ - Value {type} - """.format(**typedef)) - - if typedef['dest']: - _fwrite(outfile, """\ - Destination *{type} - """.format(**typedef)) - - _fwrite(outfile, "\n}\n\n") - - _fwrite(outfile, """\ - // String returns a readable representation of this value - // (for usage defaults) - func (f {name}Flag) String() string {{ - return FlagStringer(f) - }} - - // GetName returns the name of the flag - func (f {name}Flag) GetName() string {{ - return f.Name - }} - - // IsRequired returns the whether or not the flag is required - func (f {name}Flag) IsRequired() bool {{ - return f.Required - }} - - // {name} looks up the value of a local {name}Flag, returns - // {context_default} if not found - func (c *Context) {name}(name string) {context_type} {{ - return lookup{name}(name, c.flagSet) - }} - - // Global{name} looks up the value of a global {name}Flag, returns - // {context_default} if not found - func (c *Context) Global{name}(name string) {context_type} {{ - if fs := lookupGlobalFlagSet(name, c); fs != nil {{ - return lookup{name}(name, fs) - }} - return {context_default} - }} - - func lookup{name}(name string, set *flag.FlagSet) {context_type} {{ - f := set.Lookup(name) - if f != nil {{ - parsed, err := {parser} - if err != nil {{ - return {context_default} - }} - return {parser_cast} - }} - return {context_default} - }} - """.format(**typedef)) - - -def _write_altsrc_flag_types(outfile, types): - _fwrite(outfile, """\ - package altsrc - - import ( - "gopkg.in/urfave/cli.v1" - ) - - // WARNING: This file is generated! - - """) - - for typedef in types: - _set_typedef_defaults(typedef) - - _fwrite(outfile, """\ - // {name}Flag is the flag type that wraps cli.{name}Flag to allow - // for other values to be specified - type {name}Flag struct {{ - cli.{name}Flag - set *flag.FlagSet - }} - - // New{name}Flag creates a new {name}Flag - func New{name}Flag(fl cli.{name}Flag) *{name}Flag {{ - return &{name}Flag{{{name}Flag: fl, set: nil}} - }} - - // Apply saves the flagSet for later usage calls, then calls the - // wrapped {name}Flag.Apply - func (f *{name}Flag) Apply(set *flag.FlagSet) {{ - f.set = set - f.{name}Flag.Apply(set) - }} - - // ApplyWithError saves the flagSet for later usage calls, then calls the - // wrapped {name}Flag.ApplyWithError - func (f *{name}Flag) ApplyWithError(set *flag.FlagSet) error {{ - f.set = set - return f.{name}Flag.ApplyWithError(set) - }} - """.format(**typedef)) - - -def _fwrite(outfile, text): - print(textwrap.dedent(text), end='', file=outfile) - - -_WRITEFUNCS = { - 'cli': _write_cli_flag_types, - 'altsrc': _write_altsrc_flag_types -} - -if __name__ == '__main__': - sys.exit(main()) diff --git a/go.mod b/go.mod index d5b55c460c..31f39cc609 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,7 @@ go 1.12 require ( github.com/BurntSushi/toml v0.3.1 + github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect + github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd // indirect gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index a2ea70251e..f3cb3d0b10 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= 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.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/runtests b/runtests index ee22bdeed5..b073dc25c5 100755 --- a/runtests +++ b/runtests @@ -34,10 +34,6 @@ def main(sysargs=sys.argv[:]): def _test(): - if check_output('go version'.split()).split()[2] < 'go1.2': - _run('go test -v .') - return - coverprofiles = [] for subpackage in ['', 'altsrc']: coverprofile = 'cli.coverprofile' @@ -57,10 +53,6 @@ def _test(): def _gfmrun(): - go_version = check_output('go version'.split()).split()[2] - if go_version < 'go1.3': - print('runtests: skip on {}'.format(go_version), file=sys.stderr) - return _run(['gfmrun', '-c', str(_gfmrun_count()), '-s', 'README.md']) @@ -74,11 +66,6 @@ def _toc(): def _gen(): - go_version = check_output('go version'.split()).split()[2] - if go_version < 'go1.5': - print('runtests: skip on {}'.format(go_version), file=sys.stderr) - return - _run('go generate ./...') _run('git diff --exit-code')