Merge pull request #154 from codegangsta/allow-writer-to-be-set
Allow writer to be set
This commit is contained in:
commit
a14c5b47c7
40
app.go
40
app.go
@ -2,8 +2,11 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,6 +44,8 @@ type App struct {
|
|||||||
Author string
|
Author string
|
||||||
// Author e-mail
|
// Author e-mail
|
||||||
Email string
|
Email string
|
||||||
|
// Writer writer to write output to
|
||||||
|
Writer io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries to find out when this binary was compiled.
|
// Tries to find out when this binary was compiled.
|
||||||
@ -62,11 +67,30 @@ func NewApp() *App {
|
|||||||
BashComplete: DefaultAppComplete,
|
BashComplete: DefaultAppComplete,
|
||||||
Action: helpCommand.Action,
|
Action: helpCommand.Action,
|
||||||
Compiled: compileTime(),
|
Compiled: compileTime(),
|
||||||
|
Author: "Author",
|
||||||
|
Email: "unknown@email",
|
||||||
|
Writer: os.Stdout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
|
// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
|
||||||
func (a *App) Run(arguments []string) error {
|
func (a *App) Run(arguments []string) error {
|
||||||
|
if HelpPrinter == nil {
|
||||||
|
defer func() {
|
||||||
|
HelpPrinter = nil
|
||||||
|
}()
|
||||||
|
|
||||||
|
HelpPrinter = func(templ string, data interface{}) {
|
||||||
|
w := tabwriter.NewWriter(a.Writer, 0, 8, 1, '\t', 0)
|
||||||
|
t := template.Must(template.New("help").Parse(templ))
|
||||||
|
err := t.Execute(w, data)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// append help to commands
|
// append help to commands
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
||||||
a.Commands = append(a.Commands, helpCommand)
|
a.Commands = append(a.Commands, helpCommand)
|
||||||
@ -88,18 +112,18 @@ func (a *App) Run(arguments []string) error {
|
|||||||
err := set.Parse(arguments[1:])
|
err := set.Parse(arguments[1:])
|
||||||
nerr := normalizeFlags(a.Flags, set)
|
nerr := normalizeFlags(a.Flags, set)
|
||||||
if nerr != nil {
|
if nerr != nil {
|
||||||
fmt.Println(nerr)
|
fmt.Fprintln(a.Writer, nerr)
|
||||||
context := NewContext(a, set, set)
|
context := NewContext(a, set, set)
|
||||||
ShowAppHelp(context)
|
ShowAppHelp(context)
|
||||||
fmt.Println("")
|
fmt.Fprintln(a.Writer)
|
||||||
return nerr
|
return nerr
|
||||||
}
|
}
|
||||||
context := NewContext(a, set, set)
|
context := NewContext(a, set, set)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Incorrect Usage.\n\n")
|
fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n")
|
||||||
ShowAppHelp(context)
|
ShowAppHelp(context)
|
||||||
fmt.Println("")
|
fmt.Fprintln(a.Writer)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +163,7 @@ func (a *App) Run(arguments []string) error {
|
|||||||
// Another entry point to the cli app, takes care of passing arguments and error handling
|
// Another entry point to the cli app, takes care of passing arguments and error handling
|
||||||
func (a *App) RunAndExitOnError() {
|
func (a *App) RunAndExitOnError() {
|
||||||
if err := a.Run(os.Args); err != nil {
|
if err := a.Run(os.Args); err != nil {
|
||||||
os.Stderr.WriteString(fmt.Sprintln(err))
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,18 +191,18 @@ func (a *App) RunAsSubcommand(ctx *Context) error {
|
|||||||
context := NewContext(a, set, ctx.globalSet)
|
context := NewContext(a, set, ctx.globalSet)
|
||||||
|
|
||||||
if nerr != nil {
|
if nerr != nil {
|
||||||
fmt.Println(nerr)
|
fmt.Fprintln(a.Writer, nerr)
|
||||||
if len(a.Commands) > 0 {
|
if len(a.Commands) > 0 {
|
||||||
ShowSubcommandHelp(context)
|
ShowSubcommandHelp(context)
|
||||||
} else {
|
} else {
|
||||||
ShowCommandHelp(ctx, context.Args().First())
|
ShowCommandHelp(ctx, context.Args().First())
|
||||||
}
|
}
|
||||||
fmt.Println("")
|
fmt.Fprintln(a.Writer)
|
||||||
return nerr
|
return nerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Incorrect Usage.\n\n")
|
fmt.Fprintf(a.Writer, "Incorrect Usage.\n\n")
|
||||||
ShowSubcommandHelp(context)
|
ShowSubcommandHelp(context)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
44
app_test.go
44
app_test.go
@ -265,6 +265,50 @@ func TestApp_ParseSliceFlags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApp_DefaultStdout(t *testing.T) {
|
||||||
|
app := cli.NewApp()
|
||||||
|
|
||||||
|
if app.Writer != os.Stdout {
|
||||||
|
t.Error("Default output writer not set.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockWriter struct {
|
||||||
|
written []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fw *mockWriter) Write(p []byte) (n int, err error) {
|
||||||
|
if fw.written == nil {
|
||||||
|
fw.written = p
|
||||||
|
} else {
|
||||||
|
fw.written = append(fw.written, p...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fw *mockWriter) GetWritten() (b []byte) {
|
||||||
|
return fw.written
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApp_SetStdout(t *testing.T) {
|
||||||
|
w := &mockWriter{}
|
||||||
|
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "test"
|
||||||
|
app.Writer = w
|
||||||
|
|
||||||
|
err := app.Run([]string{"help"})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Run error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(w.written) == 0 {
|
||||||
|
t.Error("App did not write output to desired writer.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestApp_BeforeFunc(t *testing.T) {
|
func TestApp_BeforeFunc(t *testing.T) {
|
||||||
beforeRun, subcommandRun := false, false
|
beforeRun, subcommandRun := false, false
|
||||||
beforeError := fmt.Errorf("fail")
|
beforeError := fmt.Errorf("fail")
|
||||||
|
10
command.go
10
command.go
@ -74,18 +74,18 @@ func (c Command) Run(ctx *Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Incorrect Usage.\n\n")
|
fmt.Fprint(ctx.App.Writer, "Incorrect Usage.\n\n")
|
||||||
ShowCommandHelp(ctx, c.Name)
|
ShowCommandHelp(ctx, c.Name)
|
||||||
fmt.Println("")
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nerr := normalizeFlags(c.Flags, set)
|
nerr := normalizeFlags(c.Flags, set)
|
||||||
if nerr != nil {
|
if nerr != nil {
|
||||||
fmt.Println(nerr)
|
fmt.Fprintln(ctx.App.Writer, nerr)
|
||||||
fmt.Println("")
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
ShowCommandHelp(ctx, c.Name)
|
ShowCommandHelp(ctx, c.Name)
|
||||||
fmt.Println("")
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
return nerr
|
return nerr
|
||||||
}
|
}
|
||||||
context := NewContext(ctx.App, set, ctx.globalSet)
|
context := NewContext(ctx.App, set, ctx.globalSet)
|
||||||
|
29
help.go
29
help.go
@ -1,11 +1,6 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"text/tabwriter"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The text template for the Default help topic.
|
// The text template for the Default help topic.
|
||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
@ -94,7 +89,9 @@ var helpSubcommand = Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prints help for the App
|
// Prints help for the App
|
||||||
var HelpPrinter = printHelp
|
type helpPrinter func(templ string, data interface{})
|
||||||
|
|
||||||
|
var HelpPrinter helpPrinter = nil
|
||||||
|
|
||||||
// Prints version for the App
|
// Prints version for the App
|
||||||
var VersionPrinter = printVersion
|
var VersionPrinter = printVersion
|
||||||
@ -106,9 +103,9 @@ func ShowAppHelp(c *Context) {
|
|||||||
// Prints the list of subcommands as the default app completion method
|
// Prints the list of subcommands as the default app completion method
|
||||||
func DefaultAppComplete(c *Context) {
|
func DefaultAppComplete(c *Context) {
|
||||||
for _, command := range c.App.Commands {
|
for _, command := range c.App.Commands {
|
||||||
fmt.Println(command.Name)
|
fmt.Fprintln(c.App.Writer, command.Name)
|
||||||
if command.ShortName != "" {
|
if command.ShortName != "" {
|
||||||
fmt.Println(command.ShortName)
|
fmt.Fprintln(c.App.Writer, command.ShortName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +122,7 @@ func ShowCommandHelp(c *Context, command string) {
|
|||||||
if c.App.CommandNotFound != nil {
|
if c.App.CommandNotFound != nil {
|
||||||
c.App.CommandNotFound(c, command)
|
c.App.CommandNotFound(c, command)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("No help topic for '%v'\n", command)
|
fmt.Fprintf(c.App.Writer, "No help topic for '%v'\n", command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +137,7 @@ func ShowVersion(c *Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printVersion(c *Context) {
|
func printVersion(c *Context) {
|
||||||
fmt.Printf("%v version %v\n", c.App.Name, c.App.Version)
|
fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints the lists of commands within a given context
|
// Prints the lists of commands within a given context
|
||||||
@ -159,16 +156,6 @@ func ShowCommandCompletions(ctx *Context, command string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printHelp(templ string, data interface{}) {
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
|
|
||||||
t := template.Must(template.New("help").Parse(templ))
|
|
||||||
err := t.Execute(w, data)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
w.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkVersion(c *Context) bool {
|
func checkVersion(c *Context) bool {
|
||||||
if c.GlobalBool("version") {
|
if c.GlobalBool("version") {
|
||||||
ShowVersion(c)
|
ShowVersion(c)
|
||||||
|
Loading…
Reference in New Issue
Block a user