func NewNamedNirvanaCommand(name string, option *Option) NirvanaCommand {
	if name == "" {
		name = "server"
	}
	if option == nil {
		option = NewDefaultOption()
	}
	cmd := &command{
		name:    name,
		option:  option,
		plugins: []Plugin{},
		fields:  map[string]*configField{},
		hook:    &NirvanaCommandHookFunc{},
	}
	cmd.EnablePlugin(cmd.option)
	return cmd
}
NewNamedNirvanaCommand creates a nirvana command with an unique name.
Empty name means `server`. Nil option means default option.
package config
import (
	"os"
	"reflect"
	"sort"
	"strings"
	"time"
	"github.com/caicloud/nirvana"
	"github.com/caicloud/nirvana/errors"
	"github.com/caicloud/nirvana/utils/printer"
	"github.com/spf13/cast"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)
type CustomOption interface{}
type Plugin interface {
	Name() string
	Configure(cfg *nirvana.Config) error
}
type Option struct {
	IP string `desc:"Nirvana server listening IP"`
	Port uint16 `desc:"Nirvana server listening Port"`
	Key string `desc:"TLS private key (PEM format) for HTTPS"`
	Cert string `desc:"TLS certificate (PEM format) for HTTPS"`
}
func NewDefaultOption() *Option {
	return &Option{
		IP:   "",
		Port: 8080,
	}
}
func (p *Option) Name() string {
	return ""
}
func (p *Option) Configure(cfg *nirvana.Config) error {
	cfg.Configure(
		nirvana.IP(p.IP),
		nirvana.Port(p.Port),
		nirvana.TLS(p.Cert, p.Key),
	)
	return nil
}
type NirvanaCommand interface {
	EnablePlugin(plugins ...Plugin) NirvanaCommand
	AddOption(prefix string, options ...CustomOption) NirvanaCommand
	Add(pointer interface{}, key string, shortFlag string, desc string) NirvanaCommand
	Execute(descriptors ...interface{}) error
	ExecuteWithConfig(cfg *nirvana.Config) error
	Command(cfg *nirvana.Config) *cobra.Command
	SetHook(hook NirvanaCommandHook)
	Hook() NirvanaCommandHook
}
func NewDefaultNirvanaCommand() NirvanaCommand {
	return NewNirvanaCommand(nil)
}
func NewNirvanaCommand(option *Option) NirvanaCommand {
	return NewNamedNirvanaCommand("server", option)
}