Skip to content

Commit

Permalink
Pass functions to ConfigureOptions to print version, help, tls help
Browse files Browse the repository at this point in the history
This will allow NATS Streaming to provide its own version of what
should be printed when various flags are set.

Related to #578
  • Loading branch information
kozlovic committed Sep 8, 2017
1 parent b58178d commit 8b4a02d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
5 changes: 4 additions & 1 deletion main.go
Expand Up @@ -68,7 +68,10 @@ func main() {
fs.Usage = usage

// Configure the options from the flags/config file
opts, err := server.ConfigureOptions(fs, os.Args[1:])
opts, err := server.ConfigureOptions(fs, os.Args[1:],
server.PrintServerAndExit,
fs.Usage,
server.PrintTLSHelpAndDie)
if err != nil {
server.PrintAndDie(err.Error() + "\n" + usageStr)
}
Expand Down
21 changes: 15 additions & 6 deletions server/opts.go
Expand Up @@ -921,7 +921,7 @@ func processOptions(opts *Options) {
// specific flags. On success, an options structure is returned configured
// based on the selected flags and/or configuration file.
// The command line options take precedence to the ones in the configuration file.
func ConfigureOptions(fs *flag.FlagSet, args []string) (*Options, error) {
func ConfigureOptions(fs *flag.FlagSet, args []string, printVersion, printHelp, printTLSHelp func()) (*Options, error) {
opts := &Options{}
var (
showVersion bool
Expand All @@ -932,6 +932,8 @@ func ConfigureOptions(fs *flag.FlagSet, args []string) (*Options, error) {
err error
)

fs.BoolVar(&showHelp, "h", false, "Show this message.")
fs.BoolVar(&showHelp, "help", false, "Show this message.")
fs.IntVar(&opts.Port, "port", 0, "Port to listen on.")
fs.IntVar(&opts.Port, "p", 0, "Port to listen on.")
fs.StringVar(&opts.Host, "addr", "", "Network host to listen on.")
Expand Down Expand Up @@ -990,13 +992,19 @@ func ConfigureOptions(fs *flag.FlagSet, args []string) (*Options, error) {
return nil, err
}

// Show version and exit
if showVersion {
PrintServerAndExit()
printVersion()
return nil, nil
}

if showHelp {
printHelp()
return nil, nil
}

if showTLSHelp {
PrintTLSHelpAndDie()
printTLSHelp()
return nil, nil
}

// Process args looking for non-flag options,
Expand All @@ -1005,9 +1013,10 @@ func ConfigureOptions(fs *flag.FlagSet, args []string) (*Options, error) {
if err != nil {
return nil, err
} else if showVersion {
PrintServerAndExit()
printVersion()
return nil, nil
} else if showHelp {
fs.Usage()
printHelp()
return nil, nil
}

Expand Down
42 changes: 30 additions & 12 deletions server/opts_test.go
Expand Up @@ -826,25 +826,43 @@ func TestConfigureOptions(t *testing.T) {
// We need to set it back to nil otherwise it will impact reload tests.
defer func() { FlagSnapshot = nil }()

// Ensure that Usage is called when param "help" is set
fs := flag.NewFlagSet("test", flag.ContinueOnError)
ch := make(chan bool, 1)
fs.Usage = func() {
checkPrintInvoked := func() {
ch <- true
}
if _, err := ConfigureOptions(fs, []string{"help"}); err != nil {
t.Fatalf("Error on configure: %v", err)
}
select {
case <-ch:
case <-time.After(time.Second):
t.Fatal("Should have invoked flag set's Usage")
usage := func() { panic("should not get there") }
var fs *flag.FlagSet
type testPrint struct {
args []string
version, help, tlsHelp func()
}
testFuncs := []testPrint{
testPrint{[]string{"-v"}, checkPrintInvoked, usage, PrintTLSHelpAndDie},
testPrint{[]string{"version"}, checkPrintInvoked, usage, PrintTLSHelpAndDie},
testPrint{[]string{"-h"}, PrintServerAndExit, checkPrintInvoked, PrintTLSHelpAndDie},
testPrint{[]string{"help"}, PrintServerAndExit, checkPrintInvoked, PrintTLSHelpAndDie},
testPrint{[]string{"-help_tls"}, PrintServerAndExit, usage, checkPrintInvoked},
}
for _, tf := range testFuncs {
fs = flag.NewFlagSet("test", flag.ContinueOnError)
opts, err := ConfigureOptions(fs, tf.args, tf.version, tf.help, tf.tlsHelp)
if err != nil {
t.Fatalf("Error on configure: %v", err)
}
if opts != nil {
t.Fatalf("Expected options to be nil, got %v", opts)
}
select {
case <-ch:
case <-time.After(time.Second):
t.Fatalf("Should have invoked print function for args=%v", tf.args)
}
}

// Helper function that expect parsing with given args to not produce an error.
mustNotFail := func(args []string) *Options {
fs := flag.NewFlagSet("test", flag.ContinueOnError)
opts, err := ConfigureOptions(fs, args)
opts, err := ConfigureOptions(fs, args, PrintServerAndExit, fs.Usage, PrintTLSHelpAndDie)
if err != nil {
stackFatalf(t, "Error on configure: %v", err)
}
Expand All @@ -858,7 +876,7 @@ func TestConfigureOptions(t *testing.T) {
// (flagSet would print error message about unknown flags, etc..)
silenceOuput := &bytes.Buffer{}
fs.SetOutput(silenceOuput)
opts, err := ConfigureOptions(fs, args)
opts, err := ConfigureOptions(fs, args, PrintServerAndExit, fs.Usage, PrintTLSHelpAndDie)
if opts != nil || err == nil {
stackFatalf(t, "Expected no option and an error, got opts=%v and err=%v", opts, err)
}
Expand Down

0 comments on commit 8b4a02d

Please sign in to comment.