Remove reflection on CLI init
before: ``` $ time docker --help real 0m0.177s user 0m0.000s sys 0m0.040s ``` after: ``` $ time docker --help real 0m0.010s user 0m0.000s sys 0m0.000s ``` Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
parent
24a8de2b60
commit
5c8950e84d
3 changed files with 80 additions and 15 deletions
59
api/client/commands.go
Normal file
59
api/client/commands.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package client
|
||||
|
||||
// Command returns a cli command handler if one exists
|
||||
func (cli *DockerCli) Command(name string) func(...string) error {
|
||||
return map[string]func(...string) error{
|
||||
"attach": cli.CmdAttach,
|
||||
"build": cli.CmdBuild,
|
||||
"commit": cli.CmdCommit,
|
||||
"cp": cli.CmdCp,
|
||||
"create": cli.CmdCreate,
|
||||
"diff": cli.CmdDiff,
|
||||
"events": cli.CmdEvents,
|
||||
"exec": cli.CmdExec,
|
||||
"export": cli.CmdExport,
|
||||
"history": cli.CmdHistory,
|
||||
"images": cli.CmdImages,
|
||||
"import": cli.CmdImport,
|
||||
"info": cli.CmdInfo,
|
||||
"inspect": cli.CmdInspect,
|
||||
"kill": cli.CmdKill,
|
||||
"load": cli.CmdLoad,
|
||||
"login": cli.CmdLogin,
|
||||
"logout": cli.CmdLogout,
|
||||
"logs": cli.CmdLogs,
|
||||
"network": cli.CmdNetwork,
|
||||
"network create": cli.CmdNetworkCreate,
|
||||
"network connect": cli.CmdNetworkConnect,
|
||||
"network disconnect": cli.CmdNetworkDisconnect,
|
||||
"network inspect": cli.CmdNetworkInspect,
|
||||
"network ls": cli.CmdNetworkLs,
|
||||
"network rm": cli.CmdNetworkRm,
|
||||
"pause": cli.CmdPause,
|
||||
"port": cli.CmdPort,
|
||||
"ps": cli.CmdPs,
|
||||
"pull": cli.CmdPull,
|
||||
"push": cli.CmdPush,
|
||||
"rename": cli.CmdRename,
|
||||
"restart": cli.CmdRestart,
|
||||
"rm": cli.CmdRm,
|
||||
"rmi": cli.CmdRmi,
|
||||
"run": cli.CmdRun,
|
||||
"save": cli.CmdSave,
|
||||
"search": cli.CmdSearch,
|
||||
"start": cli.CmdStart,
|
||||
"stats": cli.CmdStats,
|
||||
"stop": cli.CmdStop,
|
||||
"tag": cli.CmdTag,
|
||||
"top": cli.CmdTop,
|
||||
"unpause": cli.CmdUnpause,
|
||||
"update": cli.CmdUpdate,
|
||||
"version": cli.CmdVersion,
|
||||
"volume": cli.CmdVolume,
|
||||
"volume create": cli.CmdVolumeCreate,
|
||||
"volume inspect": cli.CmdVolumeInspect,
|
||||
"volume ls": cli.CmdVolumeLs,
|
||||
"volume rm": cli.CmdVolumeRm,
|
||||
"wait": cli.CmdWait,
|
||||
}[name]
|
||||
}
|
29
cli/cli.go
29
cli/cli.go
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
|
@ -21,7 +20,9 @@ type Cli struct {
|
|||
// Handler holds the different commands Cli will call
|
||||
// It should have methods with names starting with `Cmd` like:
|
||||
// func (h myHandler) CmdFoo(args ...string) error
|
||||
type Handler interface{}
|
||||
type Handler interface {
|
||||
Command(name string) func(...string) error
|
||||
}
|
||||
|
||||
// Initializer can be optionally implemented by a Handler to
|
||||
// initialize before each call to one of its commands.
|
||||
|
@ -50,22 +51,13 @@ func (cli *Cli) command(args ...string) (func(...string) error, error) {
|
|||
if c == nil {
|
||||
continue
|
||||
}
|
||||
camelArgs := make([]string, len(args))
|
||||
for i, s := range args {
|
||||
if len(s) == 0 {
|
||||
return nil, errors.New("empty command")
|
||||
}
|
||||
camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
||||
}
|
||||
methodName := "Cmd" + strings.Join(camelArgs, "")
|
||||
method := reflect.ValueOf(c).MethodByName(methodName)
|
||||
if method.IsValid() {
|
||||
if c, ok := c.(Initializer); ok {
|
||||
if err := c.Initialize(); err != nil {
|
||||
if cmd := c.Command(strings.Join(args, " ")); cmd != nil {
|
||||
if ci, ok := c.(Initializer); ok {
|
||||
if err := ci.Initialize(); err != nil {
|
||||
return nil, initErr{err}
|
||||
}
|
||||
}
|
||||
return method.Interface().(func(...string) error), nil
|
||||
return cmd, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("command not found")
|
||||
|
@ -103,6 +95,13 @@ func (cli *Cli) noSuchCommand(command string) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Command returns a command handler, or nil if the command does not exist
|
||||
func (cli *Cli) Command(name string) func(...string) error {
|
||||
return map[string]func(...string) error{
|
||||
"help": cli.CmdHelp,
|
||||
}[name]
|
||||
}
|
||||
|
||||
// CmdHelp displays information on a Docker command.
|
||||
//
|
||||
// If more than one command is specified, information is only shown for the first command.
|
||||
|
|
|
@ -9,3 +9,10 @@ type DaemonProxy struct{}
|
|||
func NewDaemonProxy() DaemonProxy {
|
||||
return DaemonProxy{}
|
||||
}
|
||||
|
||||
// Command returns a cli command handler if one exists
|
||||
func (p DaemonProxy) Command(name string) func(...string) error {
|
||||
return map[string]func(...string) error{
|
||||
"daemon": p.CmdDaemon,
|
||||
}[name]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue