mirror of https://github.com/docker/cli.git
Remove old cli framework.
Also consolidate the leftover packages under cli. Remove pkg/mflag. Make manpage generation work with new cobra layout. Remove remaining mflag and fix tests after rebase with master. Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
fc1a3d79f8
commit
38aca22dcd
191
cli.go
191
cli.go
|
@ -1,191 +0,0 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
)
|
||||
|
||||
// Cli represents a command line interface.
|
||||
type Cli struct {
|
||||
Stderr io.Writer
|
||||
handlers []Handler
|
||||
Usage func()
|
||||
}
|
||||
|
||||
// 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 {
|
||||
Command(name string) func(...string) error
|
||||
}
|
||||
|
||||
// Initializer can be optionally implemented by a Handler to
|
||||
// initialize before each call to one of its commands.
|
||||
type Initializer interface {
|
||||
Initialize() error
|
||||
}
|
||||
|
||||
// New instantiates a ready-to-use Cli.
|
||||
func New(handlers ...Handler) *Cli {
|
||||
// make the generic Cli object the first cli handler
|
||||
// in order to handle `docker help` appropriately
|
||||
cli := new(Cli)
|
||||
cli.handlers = append([]Handler{cli}, handlers...)
|
||||
return cli
|
||||
}
|
||||
|
||||
var errCommandNotFound = errors.New("command not found")
|
||||
|
||||
func (cli *Cli) command(args ...string) (func(...string) error, error) {
|
||||
for _, c := range cli.handlers {
|
||||
if c == nil {
|
||||
continue
|
||||
}
|
||||
if cmd := c.Command(strings.Join(args, " ")); cmd != nil {
|
||||
if ci, ok := c.(Initializer); ok {
|
||||
if err := ci.Initialize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
}
|
||||
return nil, errCommandNotFound
|
||||
}
|
||||
|
||||
// Run executes the specified command.
|
||||
func (cli *Cli) Run(args ...string) error {
|
||||
if len(args) > 1 {
|
||||
command, err := cli.command(args[:2]...)
|
||||
if err == nil {
|
||||
return command(args[2:]...)
|
||||
}
|
||||
if err != errCommandNotFound {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(args) > 0 {
|
||||
command, err := cli.command(args[0])
|
||||
if err != nil {
|
||||
if err == errCommandNotFound {
|
||||
cli.noSuchCommand(args[0])
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return command(args[1:]...)
|
||||
}
|
||||
return cli.CmdHelp()
|
||||
}
|
||||
|
||||
func (cli *Cli) noSuchCommand(command string) {
|
||||
if cli.Stderr == nil {
|
||||
cli.Stderr = os.Stderr
|
||||
}
|
||||
fmt.Fprintf(cli.Stderr, "docker: '%s' is not a docker command.\nSee 'docker --help'.\n", command)
|
||||
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.
|
||||
//
|
||||
// Usage: docker help COMMAND or docker COMMAND --help
|
||||
func (cli *Cli) CmdHelp(args ...string) error {
|
||||
if len(args) > 1 {
|
||||
command, err := cli.command(args[:2]...)
|
||||
if err == nil {
|
||||
command("--help")
|
||||
return nil
|
||||
}
|
||||
if err != errCommandNotFound {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(args) > 0 {
|
||||
command, err := cli.command(args[0])
|
||||
if err != nil {
|
||||
if err == errCommandNotFound {
|
||||
cli.noSuchCommand(args[0])
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
command("--help")
|
||||
return nil
|
||||
}
|
||||
|
||||
if cli.Usage == nil {
|
||||
flag.Usage()
|
||||
} else {
|
||||
cli.Usage()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subcmd is a subcommand of the main "docker" command.
|
||||
// A subcommand represents an action that can be performed
|
||||
// from the Docker command line client.
|
||||
//
|
||||
// To see all available subcommands, run "docker --help".
|
||||
func Subcmd(name string, synopses []string, description string, exitOnError bool) *flag.FlagSet {
|
||||
var errorHandling flag.ErrorHandling
|
||||
if exitOnError {
|
||||
errorHandling = flag.ExitOnError
|
||||
} else {
|
||||
errorHandling = flag.ContinueOnError
|
||||
}
|
||||
flags := flag.NewFlagSet(name, errorHandling)
|
||||
flags.Usage = func() {
|
||||
flags.ShortUsage()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
|
||||
flags.ShortUsage = func() {
|
||||
if len(synopses) == 0 {
|
||||
synopses = []string{""}
|
||||
}
|
||||
|
||||
// Allow for multiple command usage synopses.
|
||||
for i, synopsis := range synopses {
|
||||
lead := "\t"
|
||||
if i == 0 {
|
||||
// First line needs the word 'Usage'.
|
||||
lead = "Usage:\t"
|
||||
}
|
||||
|
||||
if synopsis != "" {
|
||||
synopsis = " " + synopsis
|
||||
}
|
||||
|
||||
fmt.Fprintf(flags.Out(), "\n%sdocker %s%s", lead, name, synopsis)
|
||||
}
|
||||
|
||||
fmt.Fprintf(flags.Out(), "\n\n%s\n", description)
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
// StatusError reports an unsuccessful exit by a command.
|
||||
type StatusError struct {
|
||||
Status string
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (e StatusError) Error() string {
|
||||
return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cobraadaptor
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -17,12 +17,6 @@ func SetupRootCommand(rootCmd *cobra.Command) {
|
|||
rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root command. Required to generate the man pages
|
||||
// and reference docs from a script outside this package.
|
||||
func (c CobraAdaptor) GetRootCommand() *cobra.Command {
|
||||
return c.rootCmd
|
||||
}
|
||||
|
||||
// FlagErrorFunc prints an error messages which matches the format of the
|
||||
// docker/docker/cli error messages
|
||||
func FlagErrorFunc(cmd *cobra.Command, err error) error {
|
15
error.go
15
error.go
|
@ -1,6 +1,9 @@
|
|||
package cli
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Errors is a list of errors.
|
||||
// Useful in a loop if you don't want to return the error right away and you want to display after the loop,
|
||||
|
@ -18,3 +21,13 @@ func (errList Errors) Error() string {
|
|||
}
|
||||
return strings.Join(out, ", ")
|
||||
}
|
||||
|
||||
// StatusError reports an unsuccessful exit by a command.
|
||||
type StatusError struct {
|
||||
Status string
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (e StatusError) Error() string {
|
||||
return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
|
||||
}
|
||||
|
|
19
usage.go
19
usage.go
|
@ -1,19 +0,0 @@
|
|||
package cli
|
||||
|
||||
// Command is the struct containing the command name and description
|
||||
type Command struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
// DockerCommandUsage lists the top level docker commands and their short usage
|
||||
var DockerCommandUsage = []Command{}
|
||||
|
||||
// DockerCommands stores all the docker command
|
||||
var DockerCommands = make(map[string]Command)
|
||||
|
||||
func init() {
|
||||
for _, cmd := range DockerCommandUsage {
|
||||
DockerCommands[cmd.Name] = cmd
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue