refactor command options

This commit is contained in:
Arpad Ryszka 2018-01-08 22:06:41 +01:00
parent 19c308fa33
commit 9f541e527a
7 changed files with 700 additions and 707 deletions

View File

@ -1,63 +0,0 @@
package main
import "flag"
type syntaxOptions struct {
usage string
example string
args []string
positional []string
syntax string
syntaxFile string
flagSet *flag.FlagSet
}
func initOptions(usage, example string, args []string) *syntaxOptions {
var o syntaxOptions
o.usage = usage
o.example = example
o.args = args
o.flagSet = flag.NewFlagSet("", flag.ContinueOnError)
o.flagSet.Usage = func() {}
o.flagSet.SetOutput(werr)
o.flagSet.StringVar(&o.syntax, "syntax-string", "", syntaxStringUsage)
o.flagSet.StringVar(&o.syntaxFile, "syntax", "", syntaxFileUsage)
return &o
}
func flagError(fs *flag.FlagSet) {
stderr()
stderr("Options:")
fs.PrintDefaults()
}
func (o *syntaxOptions) parse() (exit int) {
if err := o.flagSet.Parse(o.args); err != nil {
flagError(o.flagSet)
exit = -1
}
o.positional = o.flagSet.Args()
return
}
func (o *syntaxOptions) help() {
stdout(o.usage)
stdout()
stdout("Options:")
o.flagSet.SetOutput(wout)
o.flagSet.PrintDefaults()
stdout()
stdout(o.example)
stdout()
stdout(docRef)
}
func (o *syntaxOptions) checkHelp() bool {
if len(o.args) == 0 || o.args[0] != "-help" {
return false
}
o.help()
return true
}

View File

@ -1,15 +1,27 @@
package main package main
type checkOptions struct {
command *commandOptions
syntax *fileOptions
}
func checkSyntax(args []string) int { func checkSyntax(args []string) int {
options := initOptions(checkSyntaxUsage, checkSyntaxExample, args) var o checkOptions
if options.checkHelp() { o.command = initOptions(checkSyntaxUsage, checkSyntaxExample, args)
o.syntax = &fileOptions{flagSet: o.command.flagSet}
o.command.flagSet.StringVar(&o.syntax.inline, "syntax-string", "", syntaxStringUsage)
o.command.flagSet.StringVar(&o.syntax.fileName, "syntax", "", syntaxFileUsage)
if o.command.checkHelp() {
return 0 return 0
} }
if code := options.parse(); code != 0 { if code := o.command.parseArgs(); code != 0 {
return code return code
} }
_, code := openSyntax(options) o.syntax.positional = o.command.flagSet.Args()
_, code := openSyntax(o.syntax)
return code return code
} }

View File

@ -3,35 +3,41 @@ package main
import "github.com/aryszka/treerack" import "github.com/aryszka/treerack"
type generateOptions struct { type generateOptions struct {
*syntaxOptions command *commandOptions
syntax *fileOptions
packageName string packageName string
export bool export bool
} }
func generate(args []string) int { func generate(args []string) int {
var options generateOptions var o generateOptions
options.syntaxOptions = initOptions(generateUsage, generateExample, args) o.command = initOptions(generateUsage, generateExample, args)
options.flagSet.BoolVar(&options.export, "export", false, exportUsage) o.syntax = &fileOptions{flagSet: o.command.flagSet}
options.flagSet.StringVar(&options.packageName, "package-name", "", packageNameUsage)
if options.checkHelp() { o.command.flagSet.BoolVar(&o.export, "export", false, exportUsage)
o.command.flagSet.StringVar(&o.packageName, "package-name", "", packageNameUsage)
o.command.flagSet.StringVar(&o.syntax.inline, "syntax-string", "", syntaxStringUsage)
o.command.flagSet.StringVar(&o.syntax.fileName, "syntax", "", syntaxFileUsage)
if o.command.checkHelp() {
return 0 return 0
} }
if code := options.parse(); code != 0 { if code := o.command.parseArgs(); code != 0 {
return code return code
} }
var goptions treerack.GeneratorOptions o.syntax.positional = o.command.flagSet.Args()
goptions.PackageName = options.packageName s, code := openSyntax(o.syntax)
goptions.Export = options.export
s, code := openSyntax(options.syntaxOptions)
if code != 0 { if code != 0 {
return code return code
} }
if err := s.Generate(goptions, wout); err != nil { var g treerack.GeneratorOptions
g.PackageName = o.packageName
g.Export = o.export
if err := s.Generate(g, wout); err != nil {
stderr(err) stderr(err)
return -1 return -1
} }

View File

@ -4,12 +4,20 @@ import (
"bytes" "bytes"
"flag" "flag"
"io" "io"
"io/ioutil"
"os" "os"
"github.com/aryszka/treerack" "github.com/aryszka/treerack"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
type fileOptions struct {
inline string
fileName string
positional []string
flagSet *flag.FlagSet
}
func multipleSyntaxesError(fs *flag.FlagSet) { func multipleSyntaxesError(fs *flag.FlagSet) {
stderr("only one of syntax file or syntax string is allowed") stderr("only one of syntax file or syntax string is allowed")
stderr() stderr()
@ -24,7 +32,7 @@ func missingSyntaxError(fs *flag.FlagSet) {
fs.PrintDefaults() fs.PrintDefaults()
} }
func getSource(options *syntaxOptions) (hasInput bool, fileName string, syntax string, code int) { func getSource(options *fileOptions) (hasInput bool, fileName string, syntax string, code int) {
if len(options.positional) > 1 { if len(options.positional) > 1 {
multipleSyntaxesError(options.flagSet) multipleSyntaxesError(options.flagSet)
code = -1 code = -1
@ -32,8 +40,8 @@ func getSource(options *syntaxOptions) (hasInput bool, fileName string, syntax s
} }
hasPositional := len(options.positional) == 1 hasPositional := len(options.positional) == 1
hasFile := options.syntaxFile != "" hasFile := options.fileName != ""
hasSyntax := options.syntax != "" hasSyntax := options.inline != ""
var has bool var has bool
for _, h := range []bool{hasPositional, hasFile, hasSyntax} { for _, h := range []bool{hasPositional, hasFile, hasSyntax} {
@ -51,10 +59,10 @@ func getSource(options *syntaxOptions) (hasInput bool, fileName string, syntax s
fileName = options.positional[0] fileName = options.positional[0]
return return
case hasFile: case hasFile:
fileName = options.syntaxFile fileName = options.fileName
return return
case hasSyntax: case hasSyntax:
syntax = options.syntax syntax = options.inline
return return
} }
@ -69,15 +77,15 @@ func getSource(options *syntaxOptions) (hasInput bool, fileName string, syntax s
return return
} }
func openSyntax(options *syntaxOptions) (*treerack.Syntax, int) { func open(options *fileOptions) (io.ReadCloser, int) {
hasInput, fileName, syntax, code := getSource(options) hasInput, fileName, syntax, code := getSource(options)
if code != 0 { if code != 0 {
return nil, code return nil, code
} }
var input io.Reader var r io.ReadCloser
if hasInput { if hasInput {
input = rin r = ioutil.NopCloser(rin)
} else if fileName != "" { } else if fileName != "" {
f, err := os.Open(fileName) f, err := os.Open(fileName)
if err != nil { if err != nil {
@ -85,10 +93,18 @@ func openSyntax(options *syntaxOptions) (*treerack.Syntax, int) {
return nil, -1 return nil, -1
} }
defer f.Close() r = f
input = f
} else { } else {
input = bytes.NewBufferString(syntax) r = ioutil.NopCloser(bytes.NewBufferString(syntax))
}
return r, 0
}
func openSyntax(options *fileOptions) (*treerack.Syntax, int) {
input, code := open(options)
if code != 0 {
return nil, code
} }
s := &treerack.Syntax{} s := &treerack.Syntax{}

62
cmd/treerack/options.go Normal file
View File

@ -0,0 +1,62 @@
package main
import "flag"
type commandOptions struct {
usage string
example string
args []string
flagSet *flag.FlagSet
}
func initOptions(usage, example string, args []string) *commandOptions {
var o commandOptions
o.usage = usage
o.example = example
o.args = args
o.flagSet = flag.NewFlagSet("", flag.ContinueOnError)
o.flagSet.Usage = func() {}
o.flagSet.SetOutput(werr)
return &o
}
func (o *commandOptions) flagError() {
stderr()
stderr("Options:")
o.flagSet.PrintDefaults()
}
func (o *commandOptions) parseArgs() (exit int) {
if err := o.flagSet.Parse(o.args); err != nil {
o.flagError()
exit = -1
}
return
}
func (o *commandOptions) help() {
stdout(o.usage)
stdout()
stdout("Options:")
o.flagSet.SetOutput(wout)
o.flagSet.PrintDefaults()
stdout()
stdout(o.example)
stdout()
stdout(docRef)
}
func (o *commandOptions) checkHelp() bool {
if len(o.args) == 0 || o.args[0] != "-help" {
return false
}
o.help()
return true
}

View File

@ -1,45 +1,5 @@
package main package main
import (
"flag"
"io"
)
type parseOptions struct {
syntaxOptions
input string
inputFile string
pretty bool
indent string
}
func flagSetParse(o *parseOptions, output io.Writer) *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Usage = func() {}
fs.SetOutput(output)
fs.StringVar(&o.syntax, "syntax-string", "", syntaxStringUsage)
fs.StringVar(&o.syntaxFile, "syntax", "", syntaxFileUsage)
return fs
}
func flagErrorParse(fs *flag.FlagSet) {
stderr()
stderr("Options:")
fs.PrintDefaults()
}
func helpParse() {
stdout(parseUsage)
stdout()
stdout("Options:")
fs := flagSetParse(&parseOptions{}, wout)
fs.PrintDefaults()
stdout()
stdout(parseExample)
stdout()
stdout(docRef)
}
func parse(args []string) int { func parse(args []string) int {
return 0 return 0
} }

File diff suppressed because it is too large Load Diff