func (cmd *Command) RunWith(args []string, writer io.Writer, resp http.ResponseWriter, httpMethods ...string) error {
	fds := []uintptr{}
	if writer == nil {
		writer = colorable.NewColorableStdout()
		fds = append(fds, os.Stdout.Fd())
	}
	clr := color.Color{}
	colorSwitch(&clr, writer, fds...)
	var ctx *Context
	var suggestion string
	ctx, suggestion, err := cmd.prepare(clr, args, writer, resp, httpMethods...)
	if err == ExitError {
		return nil
	}
	if err != nil {
		if cmd.OnRootPrepareError != nil {
			err = cmd.OnRootPrepareError(err)
		}
		if err != nil {
			return wrapErr(err, suggestion, clr)
		}
		return nil
	}
	if ctx.command.NoHook {
		return ctx.command.Fn(ctx)
	}
	funcs := []func(*Context) error{
		ctx.command.OnBefore,
		cmd.OnRootBefore,
		ctx.command.Fn,
		cmd.OnRootAfter,
		ctx.command.OnAfter,
	}
	for _, f := range funcs {
		if f != nil {
			if err := f(ctx); err != nil {
				if err == ExitError {
					return nil
				}
				return err
			}
		}
	}
	return nil
}
RunWith runs the command with args and writer,httpMethods
package cli
import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"regexp"
	"sort"
	"strings"
	"sync"
	"github.com/labstack/gommon/color"
	"github.com/mattn/go-colorable"
)
var commandNameRegexp = regexp.MustCompile("^[a-zA-Z_0-9][a-zA-Z_\\-0-9]*$")
func IsValidCommandName(commandName string) bool {
	return commandNameRegexp.MatchString(commandName)
}
type (
	CommandFunc func(*Context) error
	ArgvFunc func() interface{}
	NumCheckFunc func(n int) bool
	UsageFunc func() string
)
func ExactN(num int) NumCheckFunc { return func(n int) bool { return n == num } }
func AtLeast(num int) NumCheckFunc { return func(n int) bool { return n >= num } }
func AtMost(num int) NumCheckFunc { return func(n int) bool { return n <= num } }
type (
	Command struct {
		Name    string    
		Aliases []string  
		Desc    string    
		Text    string    
		CanSubRoute bool
		NoHook bool
		Global bool
		Fn        CommandFunc   
		UsageFn   UsageFunc     
		Argv      ArgvFunc      
		NumArg    NumCheckFunc  
		NumOption NumCheckFunc  
		HTTPRouters []string
		HTTPMethods []string
		OnBefore func(*Context) error
		OnAfter  func(*Context) error
		OnRootPrepareError func(error) error
		OnRootBefore       func(*Context) error
		OnRootAfter        func(*Context) error
		routersMap map[string]string
		parent   *Command
		children []*Command
		isServer bool
		locker     sync.Mutex  
		usage      string
		usageStyle UsageStyle
	}
	CommandTree struct {
		command *Command
		forest  []*CommandTree
	}
)
func (cmd *Command) Register(child *Command) *Command {
	if child == nil {
		panic("command `" + cmd.Name + "` try register a nil command")
	}
	if !IsValidCommandName(child.Name) {
		panic("illegal command name `" + cmd.Name + "`")
	}
	if cmd.children == nil {
		cmd.children = []*Command{}
	}
	if child.parent != nil {
		panic("command `" + child.Name + "` has been child of `" + child.parent.Name + "`")
	}
	if cmd.findChild(child.Name) != nil {
		panic("repeat register child `" + child.Name + "` for command `" + cmd.Name + "`")
	}
	if child.Aliases != nil {
		for _, alias := range child.Aliases {
			if cmd.findChild(alias) != nil {
				panic("repeat register child `" + alias + "` for command `" + cmd.Name + "`")
			}
		}
	}
	cmd.children = append(cmd.children, child)
	child.parent = cmd
	return child
}
func (cmd *Command) RegisterFunc(name string, fn CommandFunc, argvFn ArgvFunc) *Command {
	return cmd.Register(&Command{Name: name, Fn: fn, Argv: argvFn})
}
func (cmd *Command) RegisterTree(forest ...*CommandTree) {
	for _, tree := range forest {
		cmd.Register(tree.command)
		if tree.forest != nil && len(tree.forest) > 0 {
			tree.command.RegisterTree(tree.forest...)
		}
	}
}
func (cmd *Command) Parent() *Command {
	return cmd.parent
}
func (cmd *Command) IsServer() bool {
	return cmd.isServer
}
func (cmd *Command) IsClient() bool {
	return !cmd.IsServer()
}
func (cmd *Command) SetIsServer(yes bool) {
	cmd.Root().isServer = yes
}
func (cmd *Command) Run(args []string) error {
	return cmd.RunWith(args, nil, nil)
}