fix(exit): add optional "exit" final arg to Parse()
Users of docopt.go should be able to handle their own return
codes and os.Exit() processing. Calling the Parse() func with
an extra last arg of "false" means docopt.go will not call
os.Exit().
Additionally, the docopt_test.go suite was changed to call the
exported Parse() func instead of the parse() implementation.
Fixes #7.
diff --git a/docopt.go b/docopt.go
index 1e4ab0b..e513ae5 100644
--- a/docopt.go
+++ b/docopt.go
@@ -85,14 +85,24 @@
// "<port>": "8"',
// "serial": false,
// "tcp": true}
-func Parse(doc string, argv []string, help bool, version string, optionsFirst bool) (map[string]interface{}, error) {
+func Parse(doc string, argv []string, help bool, version string,
+ optionsFirst bool, exit ...bool) (map[string]interface{}, error) {
+ // if "false" was the (optional) last arg, don't call os.Exit()
+ exitOk := true
+ if len(exit) > 0 {
+ exitOk = exit[0]
+ }
args, output, err := parse(doc, argv, help, version, optionsFirst)
if _, ok := err.(*UserError); ok {
fmt.Println(output)
- os.Exit(1)
+ if exitOk {
+ os.Exit(1)
+ }
} else if len(output) > 0 && err == nil {
fmt.Println(output)
- os.Exit(0)
+ if exitOk {
+ os.Exit(0)
+ }
}
return args, err
}
diff --git a/docopt_test.go b/docopt_test.go
index 6609acc..6354b00 100644
--- a/docopt_test.go
+++ b/docopt_test.go
@@ -11,6 +11,7 @@
"bytes"
"encoding/json"
"fmt"
+ "io"
"io/ioutil"
"os"
"reflect"
@@ -118,25 +119,25 @@
}
func TestCommands(t *testing.T) {
- if v, _, err := parse("Usage: prog add", []string{"add"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
+ if v, err := Parse("Usage: prog add", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
t.Error(err)
}
- if v, _, err := parse("Usage: prog [add]", []string{}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"add": false}) != true {
+ if v, err := Parse("Usage: prog [add]", []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": false}) != true {
t.Error(err)
}
- if v, _, err := parse("Usage: prog [add]", []string{"add"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
+ if v, err := Parse("Usage: prog [add]", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true}) != true {
t.Error(err)
}
- if v, _, err := parse("Usage: prog (add|rm)", []string{"add"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"add": true, "rm": false}) != true {
+ if v, err := Parse("Usage: prog (add|rm)", []string{"add"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": true, "rm": false}) != true {
t.Error(err)
}
- if v, _, err := parse("Usage: prog (add|rm)", []string{"rm"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"add": false, "rm": true}) != true {
+ if v, err := Parse("Usage: prog (add|rm)", []string{"rm"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"add": false, "rm": true}) != true {
t.Error(err)
}
- if v, _, err := parse("Usage: prog a b", []string{"a", "b"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"a": true, "b": true}) != true {
+ if v, err := Parse("Usage: prog a b", []string{"a", "b"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"a": true, "b": true}) != true {
t.Error(err)
}
- _, _, err := parse("Usage: prog a b", []string{"b", "a"}, true, "", false)
+ _, err := Parse("Usage: prog a b", []string{"b", "a"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
@@ -1063,73 +1064,73 @@
}
func TestLongOptionsErrorHandling(t *testing.T) {
- _, _, err := parse("Usage: prog", []string{"--non-existent"}, true, "", false)
+ _, err := Parse("Usage: prog", []string{"--non-existent"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
}
- _, _, err = parse("Usage: prog [--version --verbose]\nOptions: --version\n --verbose",
- []string{"--ver"}, true, "", false)
+ _, err = Parse("Usage: prog [--version --verbose]\nOptions: --version\n --verbose",
+ []string{"--ver"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog --long\nOptions: --long ARG", []string{}, true, "", false)
+ _, err = Parse("Usage: prog --long\nOptions: --long ARG", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog --long ARG\nOptions: --long ARG",
- []string{"--long"}, true, "", false)
+ _, err = Parse("Usage: prog --long ARG\nOptions: --long ARG",
+ []string{"--long"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
}
- _, _, err = parse("Usage: prog --long=ARG\nOptions: --long", []string{}, true, "", false)
+ _, err = Parse("Usage: prog --long=ARG\nOptions: --long", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog --long\nOptions: --long",
- []string{}, true, "--long=ARG", false)
+ _, err = Parse("Usage: prog --long\nOptions: --long",
+ []string{}, true, "--long=ARG", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
}
func TestShortOptionsErrorHandling(t *testing.T) {
- _, _, err := parse("Usage: prog -x\nOptions: -x this\n -x that", []string{}, true, "", false)
+ _, err := Parse("Usage: prog -x\nOptions: -x this\n -x that", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(fmt.Sprintf("(%s) %s", reflect.TypeOf(err), err))
}
- _, _, err = parse("Usage: prog", []string{"-x"}, true, "", false)
+ _, err = Parse("Usage: prog", []string{"-x"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog -o\nOptions: -o ARG", []string{}, true, "", false)
+ _, err = Parse("Usage: prog -o\nOptions: -o ARG", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog -o ARG\nOptions: -o ARG", []string{"-o"}, true, "", false)
+ _, err = Parse("Usage: prog -o ARG\nOptions: -o ARG", []string{"-o"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
}
func TestMatchingParen(t *testing.T) {
- _, _, err := parse("Usage: prog [a [b]", []string{}, true, "", false)
+ _, err := Parse("Usage: prog [a [b]", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
- _, _, err = parse("Usage: prog [a [b] ] c )", []string{}, true, "", false)
+ _, err = Parse("Usage: prog [a [b] ] c )", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
}
func TestAllowDoubleDash(t *testing.T) {
- if v, _, err := parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"--", "-o"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-o": false, "<arg>": "-o", "--": true}) != true {
+ if v, err := Parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"--", "-o"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-o": false, "<arg>": "-o", "--": true}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"-o", "1"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-o": true, "<arg>": "1", "--": false}) != true {
+ if v, err := Parse("usage: prog [-o] [--] <arg>\noptions: -o", []string{"-o", "1"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-o": true, "<arg>": "1", "--": false}) != true {
t.Error(err)
}
- _, _, err := parse("usage: prog [-o] <arg>\noptions:-o", []string{"-o"}, true, "", false)
+ _, err := Parse("usage: prog [-o] <arg>\noptions:-o", []string{"-o"}, true, "", false, false)
if _, ok := err.(*UserError); !ok { //"--" is not allowed; FIXME?
t.Error(err)
}
@@ -1139,10 +1140,10 @@
doc := `Usage: prog [-v] A
Options: -v Be verbose.`
- if v, _, err := parse(doc, []string{"arg"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": false, "A": "arg"}) != true {
+ if v, err := Parse(doc, []string{"arg"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": false, "A": "arg"}) != true {
t.Error(err)
}
- if v, _, err := parse(doc, []string{"-v", "arg"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "A": "arg"}) != true {
+ if v, err := Parse(doc, []string{"-v", "arg"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "A": "arg"}) != true {
t.Error(err)
}
@@ -1157,44 +1158,44 @@
--help
`
- if v, _, err := parse(doc, []string{"-v", "file.py"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": "file.py", "INPUT": nil, "OUTPUT": nil}) != true {
+ if v, err := Parse(doc, []string{"-v", "file.py"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": "file.py", "INPUT": nil, "OUTPUT": nil}) != true {
t.Error(err)
}
- if v, _, err := parse(doc, []string{"-v"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": nil, "INPUT": nil, "OUTPUT": nil}) != true {
+ if v, err := Parse(doc, []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true, "-q": false, "-r": false, "--help": false, "FILE": nil, "INPUT": nil, "OUTPUT": nil}) != true {
t.Error(err)
}
- _, _, err := parse(doc, []string{"-v", "input.py", "output.py"}, true, "", false) // does not match
+ _, err := Parse(doc, []string{"-v", "input.py", "output.py"}, true, "", false, false) // does not match
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
- _, _, err = parse(doc, []string{"--fake"}, true, "", false)
+ _, err = Parse(doc, []string{"--fake"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
- _, output, err := parse(doc, []string{"--hel"}, true, "", false)
+ _, output, err := parseOutput(doc, []string{"--hel"}, true, "", false)
if err != nil || len(output) == 0 {
t.Error(err)
}
}
func TestLanguageErrors(t *testing.T) {
- _, _, err := parse("no usage with colon here", []string{}, true, "", false)
+ _, err := Parse("no usage with colon here", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
- _, _, err = parse("usage: here \n\n and again usage: here", []string{}, true, "", false)
+ _, err = Parse("usage: here \n\n and again usage: here", []string{}, true, "", false, false)
if _, ok := err.(*LanguageError); !ok {
t.Error(err)
}
}
func TestIssue40(t *testing.T) {
- _, output, err := parse("usage: prog --help-commands | --help", []string{"--help"}, true, "", false)
+ _, output, err := parseOutput("usage: prog --help-commands | --help", []string{"--help"}, true, "", false)
if err != nil || len(output) == 0 {
t.Error(err)
}
- if v, _, err := parse("usage: prog --aabb | --aa", []string{"--aa"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--aabb": false, "--aa": true}) != true {
+ if v, err := Parse("usage: prog --aabb | --aa", []string{"--aa"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--aabb": false, "--aa": true}) != true {
t.Error(err)
}
}
@@ -1204,52 +1205,52 @@
}
func TestCountMultipleFlags(t *testing.T) {
- if v, _, err := parse("usage: prog [-v]", []string{"-v"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": true}) != true {
+ if v, err := Parse("usage: prog [-v]", []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": true}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-vv]", []string{}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": 0}) != true {
+ if v, err := Parse("usage: prog [-vv]", []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 0}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-vv]", []string{"-v"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": 1}) != true {
+ if v, err := Parse("usage: prog [-vv]", []string{"-v"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 1}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-vv]", []string{"-vv"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": 2}) != true {
+ if v, err := Parse("usage: prog [-vv]", []string{"-vv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 2}) != true {
t.Error(err)
}
- _, _, err := parse("usage: prog [-vv]", []string{"-vvv"}, true, "", false)
+ _, err := Parse("usage: prog [-vv]", []string{"-vvv"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-v | -vv | -vvv]", []string{"-vvv"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": 3}) != true {
+ if v, err := Parse("usage: prog [-v | -vv | -vvv]", []string{"-vvv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 3}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [-v...]", []string{"-vvvvvv"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-v": 6}) != true {
+ if v, err := Parse("usage: prog [-v...]", []string{"-vvvvvv"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-v": 6}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [--ver --ver]", []string{"--ver", "--ver"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--ver": 2}) != true {
+ if v, err := Parse("usage: prog [--ver --ver]", []string{"--ver", "--ver"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--ver": 2}) != true {
t.Error(err)
}
}
func TestAnyOptionsParameter(t *testing.T) {
- _, _, err := parse("usage: prog [options]",
- []string{"-foo", "--bar", "--spam=eggs"}, true, "", false)
+ _, err := Parse("usage: prog [options]",
+ []string{"-foo", "--bar", "--spam=eggs"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
- _, _, err = parse("usage: prog [options]",
- []string{"--foo", "--bar", "--bar"}, true, "", false)
+ _, err = Parse("usage: prog [options]",
+ []string{"--foo", "--bar", "--bar"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
- _, _, err = parse("usage: prog [options]",
- []string{"--bar", "--bar", "--bar", "-ffff"}, true, "", false)
+ _, err = Parse("usage: prog [options]",
+ []string{"--bar", "--bar", "--bar", "-ffff"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
- _, _, err = parse("usage: prog [options]",
- []string{"--long=arg", "--long=another"}, true, "", false)
+ _, err = Parse("usage: prog [options]",
+ []string{"--long=arg", "--long=another"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
@@ -1257,47 +1258,47 @@
func TestDefaultValueForPositionalArguments(t *testing.T) {
doc := "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x]"
- if v, _, err := parse(doc, []string{}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x"}}) != true {
+ if v, err := Parse(doc, []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x"}}) != true {
t.Error(err)
}
doc = "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x y]"
- if v, _, err := parse(doc, []string{}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x", "y"}}) != true {
+ if v, err := Parse(doc, []string{}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"x", "y"}}) != true {
t.Error(err)
}
doc = "Usage: prog [--data=<data>...]\nOptions:\n\t-d --data=<arg> Input data [default: x y]"
- if v, _, err := parse(doc, []string{"--data=this"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"this"}}) != true {
+ if v, err := Parse(doc, []string{"--data=this"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--data": []string{"this"}}) != true {
t.Error(err)
}
}
func TestIssue59(t *testing.T) {
- if v, _, err := parse("usage: prog --long=<a>", []string{"--long="}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--long": ""}) != true {
+ if v, err := Parse("usage: prog --long=<a>", []string{"--long="}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--long": ""}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog -l <a>\noptions: -l <a>", []string{"-l", ""}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"-l": ""}) != true {
+ if v, err := Parse("usage: prog -l <a>\noptions: -l <a>", []string{"-l", ""}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"-l": ""}) != true {
t.Error(err)
}
}
func TestOptionsFirst(t *testing.T) {
- if v, _, err := parse("usage: prog [--opt] [<args>...]", []string{"--opt", "this", "that"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
+ if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"--opt", "this", "that"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
+ if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", false, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": true, "<args>": []string{"this", "that"}}) != true {
t.Error(err)
}
- if v, _, err := parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", true); reflect.DeepEqual(v, map[string]interface{}{"--opt": false, "<args>": []string{"this", "that", "--opt"}}) != true {
+ if v, err := Parse("usage: prog [--opt] [<args>...]", []string{"this", "that", "--opt"}, true, "", true, false); reflect.DeepEqual(v, map[string]interface{}{"--opt": false, "<args>": []string{"this", "that", "--opt"}}) != true {
t.Error(err)
}
}
func TestIssue68OptionsShortcutDoesNotIncludeOptionsInUsagePattern(t *testing.T) {
- args, _, err := parse("usage: prog [-ab] [options]\noptions: -x\n -y", []string{"-ax"}, true, "", false)
+ args, err := Parse("usage: prog [-ab] [options]\noptions: -x\n -y", []string{"-ax"}, true, "", false, false)
if args["-a"] != true {
t.Error(err)
@@ -1315,14 +1316,14 @@
func TestIssue65EvaluateArgvWhenCalledNotWhenImported(t *testing.T) {
os.Args = strings.Fields("prog -a")
- v, _, err := parse("usage: prog [-ab]", nil, true, "", false)
+ v, err := Parse("usage: prog [-ab]", nil, true, "", false, false)
w := map[string]interface{}{"-a": true, "-b": false}
if reflect.DeepEqual(v, w) != true {
t.Error(err)
}
os.Args = strings.Fields("prog -b")
- v, _, err = parse("usage: prog [-ab]", nil, true, "", false)
+ v, err = Parse("usage: prog [-ab]", nil, true, "", false, false)
w = map[string]interface{}{"-a": false, "-b": true}
if reflect.DeepEqual(v, w) != true {
t.Error(err)
@@ -1330,14 +1331,14 @@
}
func TestIssue71DoubleDashIsNotAValidOptionArgument(t *testing.T) {
- _, _, err := parse("usage: prog [--log=LEVEL] [--] <args>...",
- []string{"--log", "--", "1", "2"}, true, "", false)
+ _, err := Parse("usage: prog [--log=LEVEL] [--] <args>...",
+ []string{"--log", "--", "1", "2"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
- _, _, err = parse(`usage: prog [-l LEVEL] [--] <args>...
- options: -l LEVEL`, []string{"-l", "--", "1", "2"}, true, "", false)
+ _, err = Parse(`usage: prog [-l LEVEL] [--] <args>...
+ options: -l LEVEL`, []string{"-l", "--", "1", "2"}, true, "", false, false)
if _, ok := err.(*UserError); !ok {
t.Error()
}
@@ -1417,7 +1418,7 @@
t.Fatal(err)
}
for _, c := range tests {
- result, _, err := parse(c.doc, c.argv, true, "", false)
+ result, err := Parse(c.doc, c.argv, true, "", false, false)
if _, ok := err.(*UserError); c.userError && !ok {
// expected a user-error
t.Error("testcase:", c.id, "result:", result)
@@ -1494,6 +1495,29 @@
return res, nil
}
+// parseOutput wraps the Parse() function to also return stdout
+func parseOutput(doc string, argv []string, help bool, version string,
+ optionsFirst bool) (map[string]interface{}, string, error) {
+ stdout := os.Stdout
+ r, w, _ := os.Pipe()
+ os.Stdout = w
+
+ args, err := Parse(doc, argv, help, version, optionsFirst, false)
+
+ outChan := make(chan string)
+ go func() {
+ var buf bytes.Buffer
+ io.Copy(&buf, r)
+ outChan <- buf.String()
+ }()
+
+ w.Close()
+ os.Stdout = stdout
+ output := <-outChan
+
+ return args, output, err
+}
+
var debugEnabled = false
func debugOn(l ...interface{}) {