Allow GetFlags to return nil. (#9)

This allows individual subcommands to indicate that they would like to
take full control of the 'args' parsing. This is useful for when 'flag'
is insufficiently groovy, or when writing wrapper programs where some
or even none of the flags need to be interpreted by the wrapper itself
(e.g. merely passed through to the target program).

Without this, invocations such as `prog subcommand -flag` will fail
because `-flag` would be interpreted as an 'unknown flag'.
diff --git a/sample-complex/ask.go b/sample-complex/ask.go
index a276a68..e348ec1 100644
--- a/sample-complex/ask.go
+++ b/sample-complex/ask.go
@@ -18,6 +18,7 @@
 	Commands: []*subcommands.Command{
 		cmdAskApple,
 		cmdAskBeer,
+		cmdAskArbitrary,
 		cmdHelp,
 	},
 }
diff --git a/sample-complex/ask_arbitrary.go b/sample-complex/ask_arbitrary.go
new file mode 100644
index 0000000..9f768a2
--- /dev/null
+++ b/sample-complex/ask_arbitrary.go
@@ -0,0 +1,43 @@
+// Copyright 2014 Marc-Antoine Ruel. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"strings"
+
+	"github.com/maruel/subcommands"
+)
+
+var cmdAskArbitrary = &subcommands.Command{
+	UsageLine: "arbitrary <anything>",
+	ShortDesc: "asks for anything you want",
+	LongDesc:  "Asks for arbitrary arguments.",
+	CommandRun: func() subcommands.CommandRun {
+		// note that askArbitraryRun has no Flags
+		return &askArbitraryRun{}
+	},
+}
+
+type askArbitraryRun struct {
+}
+
+func (c *askArbitraryRun) GetFlags() *flag.FlagSet { return nil }
+
+func (c *askArbitraryRun) Run(a subcommands.Application, args []string, env subcommands.Env) int {
+	if len(args) == 0 {
+		fmt.Fprintf(a.GetErr(), "%s: expected a question.", a.GetName())
+		return 1
+	}
+	if last := args[len(args)-1]; !strings.HasSuffix(last, "?") {
+		fmt.Fprintf(a.GetErr(), "%s: expected a question ending with `?`.", a.GetName())
+		return 1
+	}
+
+	fmt.Println("You asked:", strings.Join(args, " "))
+	fmt.Println("That's a great question!")
+	return 0
+}
diff --git a/sample-complex/main_test.go b/sample-complex/main_test.go
index 1ab7c32..15ec2a3 100644
--- a/sample-complex/main_test.go
+++ b/sample-complex/main_test.go
@@ -110,8 +110,9 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
@@ -127,8 +128,9 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
@@ -144,8 +146,9 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
@@ -160,9 +163,10 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  beer   asks for beer\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  beer       asks for beer\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
@@ -176,8 +180,9 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
@@ -192,15 +197,21 @@
 				"Usage:  sample-complex ask [command] [arguments]\n" +
 				"\n" +
 				"Commands:\n" +
-				"  apple  asks for an apple\n" +
-				"  beer   asks for beer\n" +
-				"  help   prints help about a command\n" +
+				"  apple      asks for an apple\n" +
+				"  beer       asks for beer\n" +
+				"  arbitrary  asks for anything you want\n" +
+				"  help       prints help about a command\n" +
 				"\n" +
 				"\n" +
 				"Use \"sample-complex ask help [command]\" for more information about a command.\n" +
 				"\n",
 			0,
 		},
+		{
+			[]string{"ask", "arbitrary", "-flags", "-don't", "matter?"},
+			"You asked: -flags -don't matter?\nThat's a great question!\n",
+			0,
+		},
 	}
 	for i, line := range data {
 		line := line
diff --git a/subcommands.go b/subcommands.go
index 5831a60..72d4216 100644
--- a/subcommands.go
+++ b/subcommands.go
@@ -116,6 +116,11 @@
 	Run(a Application, args []string, env Env) int
 
 	// GetFlags returns the flags for this specific command.
+	//
+	// If this returns `nil`, then any additional arguments for this command will
+	// be passed unaltered as `args` to `Run()`. This is useful to delay command
+	// line parsing for implementing, for example, wrapper commands around other
+	// scripts.
 	GetFlags() *flag.FlagSet
 }
 
@@ -248,19 +253,24 @@
 			Cmd *Command
 		}{a, c}
 		tmpl(out, helpTemplate, dict)
-		r.GetFlags().PrintDefaults()
+		if f := r.GetFlags(); f != nil {
+			f.PrintDefaults()
+		}
 		*helpUsed = true
 	}
 }
 
 // Initializes the flags for a specific CommandRun.
-func initCommand(a Application, c *Command, r CommandRun, out io.Writer, helpUsed *bool) {
+func initCommand(a Application, c *Command, r CommandRun, out io.Writer, helpUsed *bool) (hasFlags bool) {
 	f := r.GetFlags()
-	if f.Usage == nil {
-		f.Usage = getCommandUsageHandler(out, a, c, r, helpUsed)
+	if f != nil {
+		if f.Usage == nil {
+			f.Usage = getCommandUsageHandler(out, a, c, r, helpUsed)
+		}
+		f.SetOutput(out)
+		f.Init(c.Name(), flag.ContinueOnError)
 	}
-	f.SetOutput(out)
-	f.Init(c.Name(), flag.ContinueOnError)
+	return f != nil
 }
 
 // FindCommand finds a Command by name and returns it if found.
@@ -360,12 +370,18 @@
 	if c := FindNearestCommand(a, args[0]); c != nil {
 		// Initialize the flags.
 		r := c.CommandRun()
-		initCommand(a, c, r, a.GetErr(), &helpUsed)
-		if err := r.GetFlags().Parse(args[1:]); err != nil {
-			return 2
-		}
-		if helpUsed {
-			return 0
+		hasFlags := initCommand(a, c, r, a.GetErr(), &helpUsed)
+		var cmdArgs []string
+		if hasFlags {
+			if err := r.GetFlags().Parse(args[1:]); err != nil {
+				return 2
+			}
+			if helpUsed {
+				return 0
+			}
+			cmdArgs = r.GetFlags().Args()
+		} else {
+			cmdArgs = args[1:]
 		}
 		envVars := a.GetEnvVars()
 		envMap := make(map[string]EnvVar, len(envVars))
@@ -376,7 +392,7 @@
 			}
 			envMap[k] = EnvVar{val, ok}
 		}
-		return r.Run(a, r.GetFlags().Args(), envMap)
+		return r.Run(a, cmdArgs, envMap)
 	}
 
 	fmt.Fprintf(a.GetErr(), "%s: unknown command %#q\n\nRun '%s help' for usage.\n", a.GetName(), args[0], a.GetName())
@@ -456,8 +472,11 @@
 	if cmd := FindNearestCommand(a, args[0]); cmd != nil {
 		// Initialize the flags.
 		r := cmd.CommandRun()
-		initCommand(a, cmd, r, a.GetErr(), &helpUsed)
-		r.GetFlags().Usage()
+		if initCommand(a, cmd, r, a.GetErr(), &helpUsed) {
+			r.GetFlags().Usage()
+		} else {
+			getCommandUsageHandler(a.GetErr(), a, cmd, r, &helpUsed)()
+		}
 		return 0
 	}