Browse code

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>

Daniel Nephin authored on 2016/06/24 00:25:51
Showing 23 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,71 @@
0
+package command
1
+
2
+import (
3
+	"github.com/docker/docker/api/client"
4
+	"github.com/docker/docker/api/client/container"
5
+	"github.com/docker/docker/api/client/image"
6
+	"github.com/docker/docker/api/client/network"
7
+	"github.com/docker/docker/api/client/node"
8
+	"github.com/docker/docker/api/client/plugin"
9
+	"github.com/docker/docker/api/client/registry"
10
+	"github.com/docker/docker/api/client/service"
11
+	"github.com/docker/docker/api/client/stack"
12
+	"github.com/docker/docker/api/client/swarm"
13
+	"github.com/docker/docker/api/client/system"
14
+	"github.com/docker/docker/api/client/volume"
15
+	"github.com/spf13/cobra"
16
+)
17
+
18
+// AddCommands adds all the commands from api/client to the root command
19
+func AddCommands(cmd *cobra.Command, dockerCli *client.DockerCli) {
20
+	cmd.AddCommand(
21
+		node.NewNodeCommand(dockerCli),
22
+		service.NewServiceCommand(dockerCli),
23
+		stack.NewStackCommand(dockerCli),
24
+		stack.NewTopLevelDeployCommand(dockerCli),
25
+		swarm.NewSwarmCommand(dockerCli),
26
+		container.NewAttachCommand(dockerCli),
27
+		container.NewCommitCommand(dockerCli),
28
+		container.NewCopyCommand(dockerCli),
29
+		container.NewCreateCommand(dockerCli),
30
+		container.NewDiffCommand(dockerCli),
31
+		container.NewExecCommand(dockerCli),
32
+		container.NewExportCommand(dockerCli),
33
+		container.NewKillCommand(dockerCli),
34
+		container.NewLogsCommand(dockerCli),
35
+		container.NewPauseCommand(dockerCli),
36
+		container.NewPortCommand(dockerCli),
37
+		container.NewPsCommand(dockerCli),
38
+		container.NewRenameCommand(dockerCli),
39
+		container.NewRestartCommand(dockerCli),
40
+		container.NewRmCommand(dockerCli),
41
+		container.NewRunCommand(dockerCli),
42
+		container.NewStartCommand(dockerCli),
43
+		container.NewStatsCommand(dockerCli),
44
+		container.NewStopCommand(dockerCli),
45
+		container.NewTopCommand(dockerCli),
46
+		container.NewUnpauseCommand(dockerCli),
47
+		container.NewUpdateCommand(dockerCli),
48
+		container.NewWaitCommand(dockerCli),
49
+		image.NewBuildCommand(dockerCli),
50
+		image.NewHistoryCommand(dockerCli),
51
+		image.NewImagesCommand(dockerCli),
52
+		image.NewLoadCommand(dockerCli),
53
+		image.NewRemoveCommand(dockerCli),
54
+		image.NewSaveCommand(dockerCli),
55
+		image.NewPullCommand(dockerCli),
56
+		image.NewPushCommand(dockerCli),
57
+		image.NewSearchCommand(dockerCli),
58
+		image.NewImportCommand(dockerCli),
59
+		image.NewTagCommand(dockerCli),
60
+		network.NewNetworkCommand(dockerCli),
61
+		system.NewEventsCommand(dockerCli),
62
+		system.NewInspectCommand(dockerCli),
63
+		registry.NewLoginCommand(dockerCli),
64
+		registry.NewLogoutCommand(dockerCli),
65
+		system.NewVersionCommand(dockerCli),
66
+		volume.NewVolumeCommand(dockerCli),
67
+		system.NewInfoCommand(dockerCli),
68
+	)
69
+	plugin.NewPluginCommand(cmd, dockerCli)
70
+}
0 71
deleted file mode 100644
... ...
@@ -1,6 +0,0 @@
1
-package client
2
-
3
-// Command returns a cli command handler if one exists
4
-func (cli *DockerCli) Command(name string) func(...string) error {
5
-	return map[string]func(...string) error{}[name]
6
-}
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	"github.com/Sirupsen/logrus"
15 15
 	"github.com/docker/docker/api/client"
16 16
 	"github.com/docker/docker/cli"
17
-	"github.com/docker/docker/cli/cobraadaptor"
18 17
 	opttypes "github.com/docker/docker/opts"
19 18
 	"github.com/docker/docker/pkg/promise"
20 19
 	"github.com/docker/docker/pkg/signal"
... ...
@@ -70,7 +69,7 @@ func NewRunCommand(dockerCli *client.DockerCli) *cobra.Command {
70 70
 
71 71
 func flagErrorFunc(cmd *cobra.Command, err error) error {
72 72
 	return cli.StatusError{
73
-		Status:     cobraadaptor.FlagErrorFunc(cmd, err).Error(),
73
+		Status:     cli.FlagErrorFunc(cmd, err).Error(),
74 74
 		StatusCode: 125,
75 75
 	}
76 76
 }
77 77
deleted file mode 100644
... ...
@@ -1,191 +0,0 @@
1
-package cli
2
-
3
-import (
4
-	"errors"
5
-	"fmt"
6
-	"io"
7
-	"os"
8
-	"strings"
9
-
10
-	flag "github.com/docker/docker/pkg/mflag"
11
-)
12
-
13
-// Cli represents a command line interface.
14
-type Cli struct {
15
-	Stderr   io.Writer
16
-	handlers []Handler
17
-	Usage    func()
18
-}
19
-
20
-// Handler holds the different commands Cli will call
21
-// It should have methods with names starting with `Cmd` like:
22
-// 	func (h myHandler) CmdFoo(args ...string) error
23
-type Handler interface {
24
-	Command(name string) func(...string) error
25
-}
26
-
27
-// Initializer can be optionally implemented by a Handler to
28
-// initialize before each call to one of its commands.
29
-type Initializer interface {
30
-	Initialize() error
31
-}
32
-
33
-// New instantiates a ready-to-use Cli.
34
-func New(handlers ...Handler) *Cli {
35
-	// make the generic Cli object the first cli handler
36
-	// in order to handle `docker help` appropriately
37
-	cli := new(Cli)
38
-	cli.handlers = append([]Handler{cli}, handlers...)
39
-	return cli
40
-}
41
-
42
-var errCommandNotFound = errors.New("command not found")
43
-
44
-func (cli *Cli) command(args ...string) (func(...string) error, error) {
45
-	for _, c := range cli.handlers {
46
-		if c == nil {
47
-			continue
48
-		}
49
-		if cmd := c.Command(strings.Join(args, " ")); cmd != nil {
50
-			if ci, ok := c.(Initializer); ok {
51
-				if err := ci.Initialize(); err != nil {
52
-					return nil, err
53
-				}
54
-			}
55
-			return cmd, nil
56
-		}
57
-	}
58
-	return nil, errCommandNotFound
59
-}
60
-
61
-// Run executes the specified command.
62
-func (cli *Cli) Run(args ...string) error {
63
-	if len(args) > 1 {
64
-		command, err := cli.command(args[:2]...)
65
-		if err == nil {
66
-			return command(args[2:]...)
67
-		}
68
-		if err != errCommandNotFound {
69
-			return err
70
-		}
71
-	}
72
-	if len(args) > 0 {
73
-		command, err := cli.command(args[0])
74
-		if err != nil {
75
-			if err == errCommandNotFound {
76
-				cli.noSuchCommand(args[0])
77
-				return nil
78
-			}
79
-			return err
80
-		}
81
-		return command(args[1:]...)
82
-	}
83
-	return cli.CmdHelp()
84
-}
85
-
86
-func (cli *Cli) noSuchCommand(command string) {
87
-	if cli.Stderr == nil {
88
-		cli.Stderr = os.Stderr
89
-	}
90
-	fmt.Fprintf(cli.Stderr, "docker: '%s' is not a docker command.\nSee 'docker --help'.\n", command)
91
-	os.Exit(1)
92
-}
93
-
94
-// Command returns a command handler, or nil if the command does not exist
95
-func (cli *Cli) Command(name string) func(...string) error {
96
-	return map[string]func(...string) error{
97
-		"help": cli.CmdHelp,
98
-	}[name]
99
-}
100
-
101
-// CmdHelp displays information on a Docker command.
102
-//
103
-// If more than one command is specified, information is only shown for the first command.
104
-//
105
-// Usage: docker help COMMAND or docker COMMAND --help
106
-func (cli *Cli) CmdHelp(args ...string) error {
107
-	if len(args) > 1 {
108
-		command, err := cli.command(args[:2]...)
109
-		if err == nil {
110
-			command("--help")
111
-			return nil
112
-		}
113
-		if err != errCommandNotFound {
114
-			return err
115
-		}
116
-	}
117
-	if len(args) > 0 {
118
-		command, err := cli.command(args[0])
119
-		if err != nil {
120
-			if err == errCommandNotFound {
121
-				cli.noSuchCommand(args[0])
122
-				return nil
123
-			}
124
-			return err
125
-		}
126
-		command("--help")
127
-		return nil
128
-	}
129
-
130
-	if cli.Usage == nil {
131
-		flag.Usage()
132
-	} else {
133
-		cli.Usage()
134
-	}
135
-
136
-	return nil
137
-}
138
-
139
-// Subcmd is a subcommand of the main "docker" command.
140
-// A subcommand represents an action that can be performed
141
-// from the Docker command line client.
142
-//
143
-// To see all available subcommands, run "docker --help".
144
-func Subcmd(name string, synopses []string, description string, exitOnError bool) *flag.FlagSet {
145
-	var errorHandling flag.ErrorHandling
146
-	if exitOnError {
147
-		errorHandling = flag.ExitOnError
148
-	} else {
149
-		errorHandling = flag.ContinueOnError
150
-	}
151
-	flags := flag.NewFlagSet(name, errorHandling)
152
-	flags.Usage = func() {
153
-		flags.ShortUsage()
154
-		flags.PrintDefaults()
155
-	}
156
-
157
-	flags.ShortUsage = func() {
158
-		if len(synopses) == 0 {
159
-			synopses = []string{""}
160
-		}
161
-
162
-		// Allow for multiple command usage synopses.
163
-		for i, synopsis := range synopses {
164
-			lead := "\t"
165
-			if i == 0 {
166
-				// First line needs the word 'Usage'.
167
-				lead = "Usage:\t"
168
-			}
169
-
170
-			if synopsis != "" {
171
-				synopsis = " " + synopsis
172
-			}
173
-
174
-			fmt.Fprintf(flags.Out(), "\n%sdocker %s%s", lead, name, synopsis)
175
-		}
176
-
177
-		fmt.Fprintf(flags.Out(), "\n\n%s\n", description)
178
-	}
179
-
180
-	return flags
181
-}
182
-
183
-// StatusError reports an unsuccessful exit by a command.
184
-type StatusError struct {
185
-	Status     string
186
-	StatusCode int
187
-}
188
-
189
-func (e StatusError) Error() string {
190
-	return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
191
-}
192 1
new file mode 100644
... ...
@@ -0,0 +1,54 @@
0
+package cli
1
+
2
+import (
3
+	"fmt"
4
+
5
+	"github.com/spf13/cobra"
6
+)
7
+
8
+// SetupRootCommand sets default usage, help, and error handling for the
9
+// root command.
10
+func SetupRootCommand(rootCmd *cobra.Command) {
11
+	rootCmd.SetUsageTemplate(usageTemplate)
12
+	rootCmd.SetHelpTemplate(helpTemplate)
13
+	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
14
+
15
+	rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
16
+	rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
17
+}
18
+
19
+// FlagErrorFunc prints an error messages which matches the format of the
20
+// docker/docker/cli error messages
21
+func FlagErrorFunc(cmd *cobra.Command, err error) error {
22
+	if err == nil {
23
+		return err
24
+	}
25
+
26
+	usage := ""
27
+	if cmd.HasSubCommands() {
28
+		usage = "\n\n" + cmd.UsageString()
29
+	}
30
+	return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage)
31
+}
32
+
33
+var usageTemplate = `Usage:	{{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}}
34
+
35
+{{ .Short | trim }}{{if gt .Aliases 0}}
36
+
37
+Aliases:
38
+  {{.NameAndAliases}}{{end}}{{if .HasExample}}
39
+
40
+Examples:
41
+{{ .Example }}{{end}}{{if .HasFlags}}
42
+
43
+Options:
44
+{{.Flags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableSubCommands}}
45
+
46
+Commands:{{range .Commands}}{{if .IsAvailableCommand}}
47
+  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasSubCommands }}
48
+
49
+Run '{{.CommandPath}} COMMAND --help' for more information on a command.{{end}}
50
+`
51
+
52
+var helpTemplate = `
53
+{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
0 54
deleted file mode 100644
... ...
@@ -1,60 +0,0 @@
1
-package cobraadaptor
2
-
3
-import (
4
-	"fmt"
5
-
6
-	"github.com/spf13/cobra"
7
-)
8
-
9
-// SetupRootCommand sets default usage, help, and error handling for the
10
-// root command.
11
-func SetupRootCommand(rootCmd *cobra.Command) {
12
-	rootCmd.SetUsageTemplate(usageTemplate)
13
-	rootCmd.SetHelpTemplate(helpTemplate)
14
-	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
15
-
16
-	rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
17
-	rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
18
-}
19
-
20
-// GetRootCommand returns the root command. Required to generate the man pages
21
-// and reference docs from a script outside this package.
22
-func (c CobraAdaptor) GetRootCommand() *cobra.Command {
23
-	return c.rootCmd
24
-}
25
-
26
-// FlagErrorFunc prints an error messages which matches the format of the
27
-// docker/docker/cli error messages
28
-func FlagErrorFunc(cmd *cobra.Command, err error) error {
29
-	if err == nil {
30
-		return err
31
-	}
32
-
33
-	usage := ""
34
-	if cmd.HasSubCommands() {
35
-		usage = "\n\n" + cmd.UsageString()
36
-	}
37
-	return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage)
38
-}
39
-
40
-var usageTemplate = `Usage:	{{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}}
41
-
42
-{{ .Short | trim }}{{if gt .Aliases 0}}
43
-
44
-Aliases:
45
-  {{.NameAndAliases}}{{end}}{{if .HasExample}}
46
-
47
-Examples:
48
-{{ .Example }}{{end}}{{if .HasFlags}}
49
-
50
-Options:
51
-{{.Flags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableSubCommands}}
52
-
53
-Commands:{{range .Commands}}{{if .IsAvailableCommand}}
54
-  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasSubCommands }}
55
-
56
-Run '{{.CommandPath}} COMMAND --help' for more information on a command.{{end}}
57
-`
58
-
59
-var helpTemplate = `
60
-{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
... ...
@@ -1,6 +1,9 @@
1 1
 package cli
2 2
 
3
-import "strings"
3
+import (
4
+	"fmt"
5
+	"strings"
6
+)
4 7
 
5 8
 // Errors is a list of errors.
6 9
 // 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 {
18 18
 	}
19 19
 	return strings.Join(out, ", ")
20 20
 }
21
+
22
+// StatusError reports an unsuccessful exit by a command.
23
+type StatusError struct {
24
+	Status     string
25
+	StatusCode int
26
+}
27
+
28
+func (e StatusError) Error() string {
29
+	return fmt.Sprintf("Status: %s, Code: %d", e.Status, e.StatusCode)
30
+}
21 31
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-package cli
2
-
3
-// Command is the struct containing the command name and description
4
-type Command struct {
5
-	Name        string
6
-	Description string
7
-}
8
-
9
-// DockerCommandUsage lists the top level docker commands and their short usage
10
-var DockerCommandUsage = []Command{}
11
-
12
-// DockerCommands stores all the docker command
13
-var DockerCommands = make(map[string]Command)
14
-
15
-func init() {
16
-	for _, cmd := range DockerCommandUsage {
17
-		DockerCommands[cmd.Name] = cmd
18
-	}
19
-}
... ...
@@ -6,19 +6,8 @@ import (
6 6
 
7 7
 	"github.com/Sirupsen/logrus"
8 8
 	"github.com/docker/docker/api/client"
9
-	"github.com/docker/docker/api/client/container"
10
-	"github.com/docker/docker/api/client/image"
11
-	"github.com/docker/docker/api/client/network"
12
-	"github.com/docker/docker/api/client/node"
13
-	"github.com/docker/docker/api/client/plugin"
14
-	"github.com/docker/docker/api/client/registry"
15
-	"github.com/docker/docker/api/client/service"
16
-	"github.com/docker/docker/api/client/stack"
17
-	"github.com/docker/docker/api/client/swarm"
18
-	"github.com/docker/docker/api/client/system"
19
-	"github.com/docker/docker/api/client/volume"
9
+	"github.com/docker/docker/api/client/command"
20 10
 	"github.com/docker/docker/cli"
21
-	"github.com/docker/docker/cli/cobraadaptor"
22 11
 	cliflags "github.com/docker/docker/cli/flags"
23 12
 	"github.com/docker/docker/cliconfig"
24 13
 	"github.com/docker/docker/dockerversion"
... ...
@@ -50,7 +39,7 @@ func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
50 50
 			return dockerCli.Initialize(opts)
51 51
 		},
52 52
 	}
53
-	cobraadaptor.SetupRootCommand(cmd)
53
+	cli.SetupRootCommand(cmd)
54 54
 
55 55
 	flags := cmd.Flags()
56 56
 	flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit")
... ...
@@ -58,57 +47,8 @@ func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command {
58 58
 	opts.Common.InstallFlags(flags)
59 59
 
60 60
 	cmd.SetOutput(dockerCli.Out())
61
-	cmd.AddCommand(
62
-		newDaemonCommand(),
63
-		node.NewNodeCommand(dockerCli),
64
-		service.NewServiceCommand(dockerCli),
65
-		stack.NewStackCommand(dockerCli),
66
-		stack.NewTopLevelDeployCommand(dockerCli),
67
-		swarm.NewSwarmCommand(dockerCli),
68
-		container.NewAttachCommand(dockerCli),
69
-		container.NewCommitCommand(dockerCli),
70
-		container.NewCopyCommand(dockerCli),
71
-		container.NewCreateCommand(dockerCli),
72
-		container.NewDiffCommand(dockerCli),
73
-		container.NewExecCommand(dockerCli),
74
-		container.NewExportCommand(dockerCli),
75
-		container.NewKillCommand(dockerCli),
76
-		container.NewLogsCommand(dockerCli),
77
-		container.NewPauseCommand(dockerCli),
78
-		container.NewPortCommand(dockerCli),
79
-		container.NewPsCommand(dockerCli),
80
-		container.NewRenameCommand(dockerCli),
81
-		container.NewRestartCommand(dockerCli),
82
-		container.NewRmCommand(dockerCli),
83
-		container.NewRunCommand(dockerCli),
84
-		container.NewStartCommand(dockerCli),
85
-		container.NewStatsCommand(dockerCli),
86
-		container.NewStopCommand(dockerCli),
87
-		container.NewTopCommand(dockerCli),
88
-		container.NewUnpauseCommand(dockerCli),
89
-		container.NewUpdateCommand(dockerCli),
90
-		container.NewWaitCommand(dockerCli),
91
-		image.NewBuildCommand(dockerCli),
92
-		image.NewHistoryCommand(dockerCli),
93
-		image.NewImagesCommand(dockerCli),
94
-		image.NewLoadCommand(dockerCli),
95
-		image.NewRemoveCommand(dockerCli),
96
-		image.NewSaveCommand(dockerCli),
97
-		image.NewPullCommand(dockerCli),
98
-		image.NewPushCommand(dockerCli),
99
-		image.NewSearchCommand(dockerCli),
100
-		image.NewImportCommand(dockerCli),
101
-		image.NewTagCommand(dockerCli),
102
-		network.NewNetworkCommand(dockerCli),
103
-		system.NewEventsCommand(dockerCli),
104
-		system.NewInspectCommand(dockerCli),
105
-		registry.NewLoginCommand(dockerCli),
106
-		registry.NewLogoutCommand(dockerCli),
107
-		system.NewVersionCommand(dockerCli),
108
-		volume.NewVolumeCommand(dockerCli),
109
-		system.NewInfoCommand(dockerCli),
110
-	)
111
-	plugin.NewPluginCommand(cmd, dockerCli)
61
+	cmd.AddCommand(newDaemonCommand())
62
+	command.AddCommands(cmd, dockerCli)
112 63
 
113 64
 	return cmd
114 65
 }
115 66
deleted file mode 100644
... ...
@@ -1,22 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"sort"
5
-
6
-	"github.com/docker/docker/cli"
7
-)
8
-
9
-type byName []cli.Command
10
-
11
-func (a byName) Len() int           { return len(a) }
12
-func (a byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
13
-func (a byName) Less(i, j int) bool { return a[i].Name < a[j].Name }
14
-
15
-// TODO(tiborvass): do not show 'daemon' on client-only binaries
16
-
17
-func sortCommands(commands []cli.Command) []cli.Command {
18
-	dockerCommands := make([]cli.Command, len(commands))
19
-	copy(dockerCommands, commands)
20
-	sort.Sort(byName(dockerCommands))
21
-	return dockerCommands
22
-}
23 1
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"sort"
5
-	"testing"
6
-
7
-	"github.com/docker/docker/cli"
8
-)
9
-
10
-// Tests if the subcommands of docker are sorted
11
-func TestDockerSubcommandsAreSorted(t *testing.T) {
12
-	if !sort.IsSorted(byName(cli.DockerCommandUsage)) {
13
-		t.Fatal("Docker subcommands are not in sorted order")
14
-	}
15
-}
... ...
@@ -130,7 +130,7 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
130 130
 func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) {
131 131
 	content := `{
132 132
 		"registry-mirrors": ["https://mirrors.docker.com"],
133
-		"insecure-registries": ["https://insecure.docker.com"],
133
+		"insecure-registries": ["https://insecure.docker.com"]
134 134
 	}`
135 135
 	tempFile := tempfile.NewTempFile(t, "config", content)
136 136
 	defer tempFile.Remove()
... ...
@@ -3,8 +3,6 @@
3 3
 package main
4 4
 
5 5
 import (
6
-	"io/ioutil"
7
-	"os"
8 6
 	"testing"
9 7
 
10 8
 	"github.com/docker/docker/daemon"
... ...
@@ -102,30 +100,13 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
102 102
 }
103 103
 
104 104
 func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) {
105
-	c := &daemon.Config{}
106
-	common := &cliflags.CommonFlags{}
107
-	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
108
-	c.ServiceOptions.InstallCliFlags(flags, absentFromHelp)
109
-
110
-	f, err := ioutil.TempFile("", "docker-config-")
111
-	if err != nil {
112
-		t.Fatal(err)
113
-	}
114
-	configFile := f.Name()
115
-	defer os.Remove(configFile)
116
-
117
-	f.Write([]byte(`{"disable-legacy-registry": true}`))
118
-	f.Close()
119
-
120
-	loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
121
-	if err != nil {
122
-		t.Fatal(err)
123
-	}
124
-	if loadedConfig == nil {
125
-		t.Fatal("expected configuration, got nil")
126
-	}
105
+	content := `{"disable-legacy-registry": true}`
106
+	tempFile := tempfile.NewTempFile(t, "config", content)
107
+	defer tempFile.Remove()
127 108
 
128
-	if !loadedConfig.V2Only {
129
-		t.Fatal("expected disable-legacy-registry to be true, got false")
130
-	}
109
+	opts := defaultOptions(tempFile.Name())
110
+	loadedConfig, err := loadDaemonCliConfig(opts)
111
+	assert.NilError(t, err)
112
+	assert.NotNil(t, loadedConfig)
113
+	assert.Equal(t, loadedConfig.V2Only, true)
131 114
 }
... ...
@@ -5,7 +5,6 @@ import (
5 5
 
6 6
 	"github.com/Sirupsen/logrus"
7 7
 	"github.com/docker/docker/cli"
8
-	"github.com/docker/docker/cli/cobraadaptor"
9 8
 	cliflags "github.com/docker/docker/cli/flags"
10 9
 	"github.com/docker/docker/daemon"
11 10
 	"github.com/docker/docker/dockerversion"
... ...
@@ -41,7 +40,7 @@ func newDaemonCommand() *cobra.Command {
41 41
 			return runDaemon(opts)
42 42
 		},
43 43
 	}
44
-	cobraadaptor.SetupRootCommand(cmd)
44
+	cli.SetupRootCommand(cmd)
45 45
 
46 46
 	flags := cmd.Flags()
47 47
 	flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
... ...
@@ -176,7 +176,7 @@ func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) {
176 176
 	flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", defaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull")
177 177
 	flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", defaultMaxConcurrentUploads, "Set the max concurrent uploads for each push")
178 178
 
179
-	cmd.StringVar(&config.SwarmDefaultAdvertiseAddr, []string{"-swarm-default-advertise-addr"}, "", usageFn("Set default address or interface for swarm advertised address"))
179
+	flags.StringVar(&config.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
180 180
 
181 181
 	config.MaxConcurrentDownloads = &maxConcurrentDownloads
182 182
 	config.MaxConcurrentUploads = &maxConcurrentUploads
... ...
@@ -4,8 +4,10 @@ import (
4 4
 	"fmt"
5 5
 	"os"
6 6
 
7
-	"github.com/docker/docker/cli/cobraadaptor"
8
-	cliflags "github.com/docker/docker/cli/flags"
7
+	"github.com/docker/docker/api/client"
8
+	"github.com/docker/docker/api/client/command"
9
+	"github.com/docker/docker/pkg/term"
10
+	"github.com/spf13/cobra"
9 11
 	"github.com/spf13/cobra/doc"
10 12
 )
11 13
 
... ...
@@ -15,10 +17,12 @@ func generateManPages(path string) error {
15 15
 		Section: "1",
16 16
 		Source:  "Docker Community",
17 17
 	}
18
-	flags := &cliflags.ClientFlags{
19
-		Common: cliflags.InitCommonFlags(),
20
-	}
21
-	cmd := cobraadaptor.NewCobraAdaptor(flags).GetRootCommand()
18
+
19
+	stdin, stdout, stderr := term.StdStreams()
20
+	dockerCli := client.NewDockerCli(stdin, stdout, stderr)
21
+	cmd := &cobra.Command{Use: "docker"}
22
+	command.AddCommands(cmd, dockerCli)
23
+
22 24
 	cmd.DisableAutoGenTag = true
23 25
 	return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{
24 26
 		Header:           header,
25 27
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-Copyright (c) 2014-2016 The Docker & Go Authors. All rights reserved.
2
-
3
-Redistribution and use in source and binary forms, with or without
4
-modification, are permitted provided that the following conditions are
5
-met:
6
-
7
-   * Redistributions of source code must retain the above copyright
8
-notice, this list of conditions and the following disclaimer.
9
-   * Redistributions in binary form must reproduce the above
10
-copyright notice, this list of conditions and the following disclaimer
11
-in the documentation and/or other materials provided with the
12
-distribution.
13
-   * Neither the name of Google Inc. nor the names of its
14
-contributors may be used to endorse or promote products derived from
15
-this software without specific prior written permission.
16
-
17
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1
deleted file mode 100644
... ...
@@ -1,40 +0,0 @@
1
-Package mflag (aka multiple-flag) implements command-line flag parsing.  
2
-It's a **hacky** fork of the [official golang package](http://golang.org/pkg/flag/)
3
-
4
-It adds:
5
-
6
-* both short and long flag version  
7
-`./example -s red` `./example --string blue`
8
-
9
-* multiple names for the same option  
10
-```
11
-$>./example -h
12
-Usage of example:
13
-  -s, --string="": a simple string
14
-```
15
-
16
-___
17
-It is very flexible on purpose, so you can do things like:  
18
-```
19
-$>./example -h
20
-Usage of example:
21
-  -s, -string, --string="": a simple string
22
-```
23
-
24
-Or:  
25
-```
26
-$>./example -h
27
-Usage of example:
28
-  -oldflag, --newflag="": a simple string
29
-```
30
-
31
-You can also hide some flags from the usage, so if we want only `--newflag`:  
32
-```
33
-$>./example -h
34
-Usage of example:
35
-  --newflag="": a simple string
36
-$>./example -oldflag str
37
-str
38
-```
39
-
40
-See [example.go](example/example.go) for more details.
41 1
deleted file mode 100644
... ...
@@ -1,37 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"fmt"
5
-
6
-	flag "github.com/docker/docker/pkg/mflag"
7
-)
8
-
9
-var (
10
-	i        int
11
-	str      string
12
-	b, b2, h bool
13
-)
14
-
15
-func init() {
16
-	flag.Bool([]string{"#hp", "#-halp"}, false, "display the halp")
17
-	flag.BoolVar(&b, []string{"b", "#bal", "#bol", "-bal"}, false, "a simple bool")
18
-	flag.BoolVar(&b, []string{"g", "#gil"}, false, "a simple bool")
19
-	flag.BoolVar(&b2, []string{"#-bool"}, false, "a simple bool")
20
-	flag.IntVar(&i, []string{"-integer", "-number"}, -1, "a simple integer")
21
-	flag.StringVar(&str, []string{"s", "#hidden", "-string"}, "", "a simple string") //-s -hidden and --string will work, but -hidden won't be in the usage
22
-	flag.BoolVar(&h, []string{"h", "#help", "-help"}, false, "display the help")
23
-	flag.StringVar(&str, []string{"mode"}, "mode1", "set the mode\nmode1: use the mode1\nmode2: use the mode2\nmode3: use the mode3")
24
-	flag.Parse()
25
-}
26
-func main() {
27
-	if h {
28
-		flag.PrintDefaults()
29
-	} else {
30
-		fmt.Printf("s/#hidden/-string: %s\n", str)
31
-		fmt.Printf("b: %t\n", b)
32
-		fmt.Printf("-bool: %t\n", b2)
33
-		fmt.Printf("-integer/-number: %d\n", i)
34
-		fmt.Printf("s/#hidden/-string(via lookup): %s\n", flag.Lookup("s").Value.String())
35
-		fmt.Printf("ARGS: %v\n", flag.Args())
36
-	}
37
-}
38 1
deleted file mode 100644
... ...
@@ -1,1280 +0,0 @@
1
-// Copyright 2014-2016 The Docker & Go Authors. All rights reserved.
2
-// Use of this source code is governed by a BSD-style
3
-// license that can be found in the LICENSE file.
4
-
5
-//	Package mflag implements command-line flag parsing.
6
-//
7
-//	Usage:
8
-//
9
-//	Define flags using flag.String(), Bool(), Int(), etc.
10
-//
11
-//	This declares an integer flag, -f or --flagname, stored in the pointer ip, with type *int.
12
-//		import flag "github.com/docker/docker/pkg/mflag"
13
-//		var ip = flag.Int([]string{"f", "-flagname"}, 1234, "help message for flagname")
14
-//	If you like, you can bind the flag to a variable using the Var() functions.
15
-//		var flagvar int
16
-//		func init() {
17
-//			// -flaghidden will work, but will be hidden from the usage
18
-//			flag.IntVar(&flagvar, []string{"f", "#flaghidden", "-flagname"}, 1234, "help message for flagname")
19
-//		}
20
-//	Or you can create custom flags that satisfy the Value interface (with
21
-//	pointer receivers) and couple them to flag parsing by
22
-//		flag.Var(&flagVal, []string{"name"}, "help message for flagname")
23
-//	For such flags, the default value is just the initial value of the variable.
24
-//
25
-//	You can also add "deprecated" flags, they are still usable, but are not shown
26
-//	in the usage and will display a warning when you try to use them. `#` before
27
-//	an option means this option is deprecated, if there is a following option
28
-//	without `#` ahead, then that's the replacement, if not, it will just be removed:
29
-//		var ip = flag.Int([]string{"#f", "#flagname", "-flagname"}, 1234, "help message for flagname")
30
-//	this will display: `Warning: '-f' is deprecated, it will be replaced by '--flagname' soon. See usage.` or
31
-//	this will display: `Warning: '-flagname' is deprecated, it will be replaced by '--flagname' soon. See usage.`
32
-//		var ip = flag.Int([]string{"f", "#flagname"}, 1234, "help message for flagname")
33
-//	will display: `Warning: '-flagname' is deprecated, it will be removed soon. See usage.`
34
-//	so you can only use `-f`.
35
-//
36
-//	You can also group one letter flags, if you declare
37
-//		var v = flag.Bool([]string{"v", "-verbose"}, false, "help message for verbose")
38
-//		var s = flag.Bool([]string{"s", "-slow"}, false, "help message for slow")
39
-//	you will be able to use the -vs or -sv
40
-//
41
-//	After all flags are defined, call
42
-//		flag.Parse()
43
-//	to parse the command line into the defined flags.
44
-//
45
-//	Flags may then be used directly. If you're using the flags themselves,
46
-//	they are all pointers; if you bind to variables, they're values.
47
-//		fmt.Println("ip has value ", *ip)
48
-//		fmt.Println("flagvar has value ", flagvar)
49
-//
50
-//	After parsing, the arguments after the flag are available as the
51
-//	slice flag.Args() or individually as flag.Arg(i).
52
-//	The arguments are indexed from 0 through flag.NArg()-1.
53
-//
54
-//	Command line flag syntax:
55
-//		-flag
56
-//		-flag=x
57
-//		-flag="x"
58
-//		-flag='x'
59
-//		-flag x  // non-boolean flags only
60
-//	One or two minus signs may be used; they are equivalent.
61
-//	The last form is not permitted for boolean flags because the
62
-//	meaning of the command
63
-//		cmd -x *
64
-//	will change if there is a file called 0, false, etc.  You must
65
-//	use the -flag=false form to turn off a boolean flag.
66
-//
67
-//	Flag parsing stops just before the first non-flag argument
68
-//	("-" is a non-flag argument) or after the terminator "--".
69
-//
70
-//	Integer flags accept 1234, 0664, 0x1234 and may be negative.
71
-//	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
72
-//	Duration flags accept any input valid for time.ParseDuration.
73
-//
74
-//	The default set of command-line flags is controlled by
75
-//	top-level functions.  The FlagSet type allows one to define
76
-//	independent sets of flags, such as to implement subcommands
77
-//	in a command-line interface. The methods of FlagSet are
78
-//	analogous to the top-level functions for the command-line
79
-//	flag set.
80
-
81
-package mflag
82
-
83
-import (
84
-	"errors"
85
-	"fmt"
86
-	"io"
87
-	"os"
88
-	"runtime"
89
-	"sort"
90
-	"strconv"
91
-	"strings"
92
-	"text/tabwriter"
93
-	"time"
94
-
95
-	"github.com/docker/docker/pkg/homedir"
96
-)
97
-
98
-// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
99
-var ErrHelp = errors.New("flag: help requested")
100
-
101
-// ErrRetry is the error returned if you need to try letter by letter
102
-var ErrRetry = errors.New("flag: retry")
103
-
104
-// -- bool Value
105
-type boolValue bool
106
-
107
-func newBoolValue(val bool, p *bool) *boolValue {
108
-	*p = val
109
-	return (*boolValue)(p)
110
-}
111
-
112
-func (b *boolValue) Set(s string) error {
113
-	v, err := strconv.ParseBool(s)
114
-	*b = boolValue(v)
115
-	return err
116
-}
117
-
118
-func (b *boolValue) Get() interface{} { return bool(*b) }
119
-
120
-func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
121
-
122
-func (b *boolValue) IsBoolFlag() bool { return true }
123
-
124
-// optional interface to indicate boolean flags that can be
125
-// supplied without "=value" text
126
-type boolFlag interface {
127
-	Value
128
-	IsBoolFlag() bool
129
-}
130
-
131
-// -- int Value
132
-type intValue int
133
-
134
-func newIntValue(val int, p *int) *intValue {
135
-	*p = val
136
-	return (*intValue)(p)
137
-}
138
-
139
-func (i *intValue) Set(s string) error {
140
-	v, err := strconv.ParseInt(s, 0, 64)
141
-	*i = intValue(v)
142
-	return err
143
-}
144
-
145
-func (i *intValue) Get() interface{} { return int(*i) }
146
-
147
-func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
148
-
149
-// -- int64 Value
150
-type int64Value int64
151
-
152
-func newInt64Value(val int64, p *int64) *int64Value {
153
-	*p = val
154
-	return (*int64Value)(p)
155
-}
156
-
157
-func (i *int64Value) Set(s string) error {
158
-	v, err := strconv.ParseInt(s, 0, 64)
159
-	*i = int64Value(v)
160
-	return err
161
-}
162
-
163
-func (i *int64Value) Get() interface{} { return int64(*i) }
164
-
165
-func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
166
-
167
-// -- uint Value
168
-type uintValue uint
169
-
170
-func newUintValue(val uint, p *uint) *uintValue {
171
-	*p = val
172
-	return (*uintValue)(p)
173
-}
174
-
175
-func (i *uintValue) Set(s string) error {
176
-	v, err := strconv.ParseUint(s, 0, 64)
177
-	*i = uintValue(v)
178
-	return err
179
-}
180
-
181
-func (i *uintValue) Get() interface{} { return uint(*i) }
182
-
183
-func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
184
-
185
-// -- uint64 Value
186
-type uint64Value uint64
187
-
188
-func newUint64Value(val uint64, p *uint64) *uint64Value {
189
-	*p = val
190
-	return (*uint64Value)(p)
191
-}
192
-
193
-func (i *uint64Value) Set(s string) error {
194
-	v, err := strconv.ParseUint(s, 0, 64)
195
-	*i = uint64Value(v)
196
-	return err
197
-}
198
-
199
-func (i *uint64Value) Get() interface{} { return uint64(*i) }
200
-
201
-func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
202
-
203
-// -- uint16 Value
204
-type uint16Value uint16
205
-
206
-func newUint16Value(val uint16, p *uint16) *uint16Value {
207
-	*p = val
208
-	return (*uint16Value)(p)
209
-}
210
-
211
-func (i *uint16Value) Set(s string) error {
212
-	v, err := strconv.ParseUint(s, 0, 16)
213
-	*i = uint16Value(v)
214
-	return err
215
-}
216
-
217
-func (i *uint16Value) Get() interface{} { return uint16(*i) }
218
-
219
-func (i *uint16Value) String() string { return fmt.Sprintf("%v", *i) }
220
-
221
-// -- string Value
222
-type stringValue string
223
-
224
-func newStringValue(val string, p *string) *stringValue {
225
-	*p = val
226
-	return (*stringValue)(p)
227
-}
228
-
229
-func (s *stringValue) Set(val string) error {
230
-	*s = stringValue(val)
231
-	return nil
232
-}
233
-
234
-func (s *stringValue) Get() interface{} { return string(*s) }
235
-
236
-func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
237
-
238
-// -- float64 Value
239
-type float64Value float64
240
-
241
-func newFloat64Value(val float64, p *float64) *float64Value {
242
-	*p = val
243
-	return (*float64Value)(p)
244
-}
245
-
246
-func (f *float64Value) Set(s string) error {
247
-	v, err := strconv.ParseFloat(s, 64)
248
-	*f = float64Value(v)
249
-	return err
250
-}
251
-
252
-func (f *float64Value) Get() interface{} { return float64(*f) }
253
-
254
-func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
255
-
256
-// -- time.Duration Value
257
-type durationValue time.Duration
258
-
259
-func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
260
-	*p = val
261
-	return (*durationValue)(p)
262
-}
263
-
264
-func (d *durationValue) Set(s string) error {
265
-	v, err := time.ParseDuration(s)
266
-	*d = durationValue(v)
267
-	return err
268
-}
269
-
270
-func (d *durationValue) Get() interface{} { return time.Duration(*d) }
271
-
272
-func (d *durationValue) String() string { return (*time.Duration)(d).String() }
273
-
274
-// Value is the interface to the dynamic value stored in a flag.
275
-// (The default value is represented as a string.)
276
-//
277
-// If a Value has an IsBoolFlag() bool method returning true,
278
-// the command-line parser makes -name equivalent to -name=true
279
-// rather than using the next command-line argument.
280
-type Value interface {
281
-	String() string
282
-	Set(string) error
283
-}
284
-
285
-// Getter is an interface that allows the contents of a Value to be retrieved.
286
-// It wraps the Value interface, rather than being part of it, because it
287
-// appeared after Go 1 and its compatibility rules. All Value types provided
288
-// by this package satisfy the Getter interface.
289
-type Getter interface {
290
-	Value
291
-	Get() interface{}
292
-}
293
-
294
-// ErrorHandling defines how to handle flag parsing errors.
295
-type ErrorHandling int
296
-
297
-// ErrorHandling strategies available when a flag parsing error occurs
298
-const (
299
-	ContinueOnError ErrorHandling = iota
300
-	ExitOnError
301
-	PanicOnError
302
-)
303
-
304
-// A FlagSet represents a set of defined flags.  The zero value of a FlagSet
305
-// has no name and has ContinueOnError error handling.
306
-type FlagSet struct {
307
-	// Usage is the function called when an error occurs while parsing flags.
308
-	// The field is a function (not a method) that may be changed to point to
309
-	// a custom error handler.
310
-	Usage      func()
311
-	ShortUsage func()
312
-
313
-	name             string
314
-	parsed           bool
315
-	actual           map[string]*Flag
316
-	formal           map[string]*Flag
317
-	args             []string // arguments after flags
318
-	errorHandling    ErrorHandling
319
-	output           io.Writer // nil means stderr; use Out() accessor
320
-	nArgRequirements []nArgRequirement
321
-}
322
-
323
-// A Flag represents the state of a flag.
324
-type Flag struct {
325
-	Names    []string // name as it appears on command line
326
-	Usage    string   // help message
327
-	Value    Value    // value as set
328
-	DefValue string   // default value (as text); for usage message
329
-}
330
-
331
-type flagSlice []string
332
-
333
-func (p flagSlice) Len() int { return len(p) }
334
-func (p flagSlice) Less(i, j int) bool {
335
-	pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-")
336
-	lpi, lpj := strings.ToLower(pi), strings.ToLower(pj)
337
-	if lpi != lpj {
338
-		return lpi < lpj
339
-	}
340
-	return pi < pj
341
-}
342
-func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
343
-
344
-// sortFlags returns the flags as a slice in lexicographical sorted order.
345
-func sortFlags(flags map[string]*Flag) []*Flag {
346
-	var list flagSlice
347
-
348
-	// The sorted list is based on the first name, when flag map might use the other names.
349
-	nameMap := make(map[string]string)
350
-
351
-	for n, f := range flags {
352
-		fName := strings.TrimPrefix(f.Names[0], "#")
353
-		nameMap[fName] = n
354
-		if len(f.Names) == 1 {
355
-			list = append(list, fName)
356
-			continue
357
-		}
358
-
359
-		found := false
360
-		for _, name := range list {
361
-			if name == fName {
362
-				found = true
363
-				break
364
-			}
365
-		}
366
-		if !found {
367
-			list = append(list, fName)
368
-		}
369
-	}
370
-	sort.Sort(list)
371
-	result := make([]*Flag, len(list))
372
-	for i, name := range list {
373
-		result[i] = flags[nameMap[name]]
374
-	}
375
-	return result
376
-}
377
-
378
-// Name returns the name of the FlagSet.
379
-func (fs *FlagSet) Name() string {
380
-	return fs.name
381
-}
382
-
383
-// Out returns the destination for usage and error messages.
384
-func (fs *FlagSet) Out() io.Writer {
385
-	if fs.output == nil {
386
-		return os.Stderr
387
-	}
388
-	return fs.output
389
-}
390
-
391
-// SetOutput sets the destination for usage and error messages.
392
-// If output is nil, os.Stderr is used.
393
-func (fs *FlagSet) SetOutput(output io.Writer) {
394
-	fs.output = output
395
-}
396
-
397
-// VisitAll visits the flags in lexicographical order, calling fn for each.
398
-// It visits all flags, even those not set.
399
-func (fs *FlagSet) VisitAll(fn func(*Flag)) {
400
-	for _, flag := range sortFlags(fs.formal) {
401
-		fn(flag)
402
-	}
403
-}
404
-
405
-// VisitAll visits the command-line flags in lexicographical order, calling
406
-// fn for each.  It visits all flags, even those not set.
407
-func VisitAll(fn func(*Flag)) {
408
-	CommandLine.VisitAll(fn)
409
-}
410
-
411
-// Visit visits the flags in lexicographical order, calling fn for each.
412
-// It visits only those flags that have been set.
413
-func (fs *FlagSet) Visit(fn func(*Flag)) {
414
-	for _, flag := range sortFlags(fs.actual) {
415
-		fn(flag)
416
-	}
417
-}
418
-
419
-// Visit visits the command-line flags in lexicographical order, calling fn
420
-// for each.  It visits only those flags that have been set.
421
-func Visit(fn func(*Flag)) {
422
-	CommandLine.Visit(fn)
423
-}
424
-
425
-// Lookup returns the Flag structure of the named flag, returning nil if none exists.
426
-func (fs *FlagSet) Lookup(name string) *Flag {
427
-	return fs.formal[name]
428
-}
429
-
430
-// IsSet indicates whether the specified flag is set in the given FlagSet
431
-func (fs *FlagSet) IsSet(name string) bool {
432
-	return fs.actual[name] != nil
433
-}
434
-
435
-// Lookup returns the Flag structure of the named command-line flag,
436
-// returning nil if none exists.
437
-func Lookup(name string) *Flag {
438
-	return CommandLine.formal[name]
439
-}
440
-
441
-// IsSet indicates whether the specified flag was specified at all on the cmd line.
442
-func IsSet(name string) bool {
443
-	return CommandLine.IsSet(name)
444
-}
445
-
446
-type nArgRequirementType int
447
-
448
-// Indicator used to pass to BadArgs function
449
-const (
450
-	Exact nArgRequirementType = iota
451
-	Max
452
-	Min
453
-)
454
-
455
-type nArgRequirement struct {
456
-	Type nArgRequirementType
457
-	N    int
458
-}
459
-
460
-// Require adds a requirement about the number of arguments for the FlagSet.
461
-// The first parameter can be Exact, Max, or Min to respectively specify the exact,
462
-// the maximum, or the minimal number of arguments required.
463
-// The actual check is done in FlagSet.CheckArgs().
464
-func (fs *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) {
465
-	fs.nArgRequirements = append(fs.nArgRequirements, nArgRequirement{nArgRequirementType, nArg})
466
-}
467
-
468
-// CheckArgs uses the requirements set by FlagSet.Require() to validate
469
-// the number of arguments. If the requirements are not met,
470
-// an error message string is returned.
471
-func (fs *FlagSet) CheckArgs() (message string) {
472
-	for _, req := range fs.nArgRequirements {
473
-		var arguments string
474
-		if req.N == 1 {
475
-			arguments = "1 argument"
476
-		} else {
477
-			arguments = fmt.Sprintf("%d arguments", req.N)
478
-		}
479
-
480
-		str := func(kind string) string {
481
-			return fmt.Sprintf("%q requires %s%s", fs.name, kind, arguments)
482
-		}
483
-
484
-		switch req.Type {
485
-		case Exact:
486
-			if fs.NArg() != req.N {
487
-				return str("")
488
-			}
489
-		case Max:
490
-			if fs.NArg() > req.N {
491
-				return str("a maximum of ")
492
-			}
493
-		case Min:
494
-			if fs.NArg() < req.N {
495
-				return str("a minimum of ")
496
-			}
497
-		}
498
-	}
499
-	return ""
500
-}
501
-
502
-// Set sets the value of the named flag.
503
-func (fs *FlagSet) Set(name, value string) error {
504
-	flag, ok := fs.formal[name]
505
-	if !ok {
506
-		return fmt.Errorf("no such flag -%v", name)
507
-	}
508
-	if err := flag.Value.Set(value); err != nil {
509
-		return err
510
-	}
511
-	if fs.actual == nil {
512
-		fs.actual = make(map[string]*Flag)
513
-	}
514
-	fs.actual[name] = flag
515
-	return nil
516
-}
517
-
518
-// Set sets the value of the named command-line flag.
519
-func Set(name, value string) error {
520
-	return CommandLine.Set(name, value)
521
-}
522
-
523
-// isZeroValue guesses whether the string represents the zero
524
-// value for a flag. It is not accurate but in practice works OK.
525
-func isZeroValue(value string) bool {
526
-	switch value {
527
-	case "false":
528
-		return true
529
-	case "":
530
-		return true
531
-	case "0":
532
-		return true
533
-	}
534
-	return false
535
-}
536
-
537
-// PrintDefaults prints, to standard error unless configured
538
-// otherwise, the default values of all defined flags in the set.
539
-func (fs *FlagSet) PrintDefaults() {
540
-	writer := tabwriter.NewWriter(fs.Out(), 20, 1, 3, ' ', 0)
541
-	home := homedir.Get()
542
-
543
-	// Don't substitute when HOME is /
544
-	if runtime.GOOS != "windows" && home == "/" {
545
-		home = ""
546
-	}
547
-
548
-	// Add a blank line between cmd description and list of options
549
-	if fs.FlagCount() > 0 {
550
-		fmt.Fprintln(writer, "")
551
-	}
552
-
553
-	fs.VisitAll(func(flag *Flag) {
554
-		names := []string{}
555
-		for _, name := range flag.Names {
556
-			if name[0] != '#' {
557
-				names = append(names, name)
558
-			}
559
-		}
560
-		if len(names) > 0 && len(flag.Usage) > 0 {
561
-			val := flag.DefValue
562
-
563
-			if home != "" && strings.HasPrefix(val, home) {
564
-				val = homedir.GetShortcutString() + val[len(home):]
565
-			}
566
-
567
-			if isZeroValue(val) {
568
-				format := "  -%s"
569
-				fmt.Fprintf(writer, format, strings.Join(names, ", -"))
570
-			} else {
571
-				format := "  -%s=%s"
572
-				fmt.Fprintf(writer, format, strings.Join(names, ", -"), val)
573
-			}
574
-			for _, line := range strings.Split(flag.Usage, "\n") {
575
-				fmt.Fprintln(writer, "\t", line)
576
-			}
577
-		}
578
-	})
579
-	writer.Flush()
580
-}
581
-
582
-// PrintDefaults prints to standard error the default values of all defined command-line flags.
583
-func PrintDefaults() {
584
-	CommandLine.PrintDefaults()
585
-}
586
-
587
-// defaultUsage is the default function to print a usage message.
588
-func defaultUsage(fs *FlagSet) {
589
-	if fs.name == "" {
590
-		fmt.Fprintf(fs.Out(), "Usage:\n")
591
-	} else {
592
-		fmt.Fprintf(fs.Out(), "Usage of %s:\n", fs.name)
593
-	}
594
-	fs.PrintDefaults()
595
-}
596
-
597
-// NOTE: Usage is not just defaultUsage(CommandLine)
598
-// because it serves (via godoc flag Usage) as the example
599
-// for how to write your own usage function.
600
-
601
-// Usage prints to standard error a usage message documenting all defined command-line flags.
602
-// The function is a variable that may be changed to point to a custom function.
603
-var Usage = func() {
604
-	fmt.Fprintf(CommandLine.Out(), "Usage of %s:\n", os.Args[0])
605
-	PrintDefaults()
606
-}
607
-
608
-// ShortUsage prints to standard error a usage message documenting the standard command layout
609
-// The function is a variable that may be changed to point to a custom function.
610
-var ShortUsage = func() {
611
-	fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0])
612
-}
613
-
614
-// FlagCount returns the number of flags that have been defined.
615
-func (fs *FlagSet) FlagCount() int { return len(sortFlags(fs.formal)) }
616
-
617
-// FlagCountUndeprecated returns the number of undeprecated flags that have been defined.
618
-func (fs *FlagSet) FlagCountUndeprecated() int {
619
-	count := 0
620
-	for _, flag := range sortFlags(fs.formal) {
621
-		for _, name := range flag.Names {
622
-			if name[0] != '#' {
623
-				count++
624
-				break
625
-			}
626
-		}
627
-	}
628
-	return count
629
-}
630
-
631
-// NFlag returns the number of flags that have been set.
632
-func (fs *FlagSet) NFlag() int { return len(fs.actual) }
633
-
634
-// NFlag returns the number of command-line flags that have been set.
635
-func NFlag() int { return len(CommandLine.actual) }
636
-
637
-// Arg returns the i'th argument.  Arg(0) is the first remaining argument
638
-// after flags have been processed.
639
-func (fs *FlagSet) Arg(i int) string {
640
-	if i < 0 || i >= len(fs.args) {
641
-		return ""
642
-	}
643
-	return fs.args[i]
644
-}
645
-
646
-// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
647
-// after flags have been processed.
648
-func Arg(i int) string {
649
-	return CommandLine.Arg(i)
650
-}
651
-
652
-// NArg is the number of arguments remaining after flags have been processed.
653
-func (fs *FlagSet) NArg() int { return len(fs.args) }
654
-
655
-// NArg is the number of arguments remaining after flags have been processed.
656
-func NArg() int { return len(CommandLine.args) }
657
-
658
-// Args returns the non-flag arguments.
659
-func (fs *FlagSet) Args() []string { return fs.args }
660
-
661
-// Args returns the non-flag command-line arguments.
662
-func Args() []string { return CommandLine.args }
663
-
664
-// BoolVar defines a bool flag with specified name, default value, and usage string.
665
-// The argument p points to a bool variable in which to store the value of the flag.
666
-func (fs *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) {
667
-	fs.Var(newBoolValue(value, p), names, usage)
668
-}
669
-
670
-// BoolVar defines a bool flag with specified name, default value, and usage string.
671
-// The argument p points to a bool variable in which to store the value of the flag.
672
-func BoolVar(p *bool, names []string, value bool, usage string) {
673
-	CommandLine.Var(newBoolValue(value, p), names, usage)
674
-}
675
-
676
-// Bool defines a bool flag with specified name, default value, and usage string.
677
-// The return value is the address of a bool variable that stores the value of the flag.
678
-func (fs *FlagSet) Bool(names []string, value bool, usage string) *bool {
679
-	p := new(bool)
680
-	fs.BoolVar(p, names, value, usage)
681
-	return p
682
-}
683
-
684
-// Bool defines a bool flag with specified name, default value, and usage string.
685
-// The return value is the address of a bool variable that stores the value of the flag.
686
-func Bool(names []string, value bool, usage string) *bool {
687
-	return CommandLine.Bool(names, value, usage)
688
-}
689
-
690
-// IntVar defines an int flag with specified name, default value, and usage string.
691
-// The argument p points to an int variable in which to store the value of the flag.
692
-func (fs *FlagSet) IntVar(p *int, names []string, value int, usage string) {
693
-	fs.Var(newIntValue(value, p), names, usage)
694
-}
695
-
696
-// IntVar defines an int flag with specified name, default value, and usage string.
697
-// The argument p points to an int variable in which to store the value of the flag.
698
-func IntVar(p *int, names []string, value int, usage string) {
699
-	CommandLine.Var(newIntValue(value, p), names, usage)
700
-}
701
-
702
-// Int defines an int flag with specified name, default value, and usage string.
703
-// The return value is the address of an int variable that stores the value of the flag.
704
-func (fs *FlagSet) Int(names []string, value int, usage string) *int {
705
-	p := new(int)
706
-	fs.IntVar(p, names, value, usage)
707
-	return p
708
-}
709
-
710
-// Int defines an int flag with specified name, default value, and usage string.
711
-// The return value is the address of an int variable that stores the value of the flag.
712
-func Int(names []string, value int, usage string) *int {
713
-	return CommandLine.Int(names, value, usage)
714
-}
715
-
716
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
717
-// The argument p points to an int64 variable in which to store the value of the flag.
718
-func (fs *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) {
719
-	fs.Var(newInt64Value(value, p), names, usage)
720
-}
721
-
722
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
723
-// The argument p points to an int64 variable in which to store the value of the flag.
724
-func Int64Var(p *int64, names []string, value int64, usage string) {
725
-	CommandLine.Var(newInt64Value(value, p), names, usage)
726
-}
727
-
728
-// Int64 defines an int64 flag with specified name, default value, and usage string.
729
-// The return value is the address of an int64 variable that stores the value of the flag.
730
-func (fs *FlagSet) Int64(names []string, value int64, usage string) *int64 {
731
-	p := new(int64)
732
-	fs.Int64Var(p, names, value, usage)
733
-	return p
734
-}
735
-
736
-// Int64 defines an int64 flag with specified name, default value, and usage string.
737
-// The return value is the address of an int64 variable that stores the value of the flag.
738
-func Int64(names []string, value int64, usage string) *int64 {
739
-	return CommandLine.Int64(names, value, usage)
740
-}
741
-
742
-// UintVar defines a uint flag with specified name, default value, and usage string.
743
-// The argument p points to a uint variable in which to store the value of the flag.
744
-func (fs *FlagSet) UintVar(p *uint, names []string, value uint, usage string) {
745
-	fs.Var(newUintValue(value, p), names, usage)
746
-}
747
-
748
-// UintVar defines a uint flag with specified name, default value, and usage string.
749
-// The argument p points to a uint  variable in which to store the value of the flag.
750
-func UintVar(p *uint, names []string, value uint, usage string) {
751
-	CommandLine.Var(newUintValue(value, p), names, usage)
752
-}
753
-
754
-// Uint defines a uint flag with specified name, default value, and usage string.
755
-// The return value is the address of a uint  variable that stores the value of the flag.
756
-func (fs *FlagSet) Uint(names []string, value uint, usage string) *uint {
757
-	p := new(uint)
758
-	fs.UintVar(p, names, value, usage)
759
-	return p
760
-}
761
-
762
-// Uint defines a uint flag with specified name, default value, and usage string.
763
-// The return value is the address of a uint  variable that stores the value of the flag.
764
-func Uint(names []string, value uint, usage string) *uint {
765
-	return CommandLine.Uint(names, value, usage)
766
-}
767
-
768
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
769
-// The argument p points to a uint64 variable in which to store the value of the flag.
770
-func (fs *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) {
771
-	fs.Var(newUint64Value(value, p), names, usage)
772
-}
773
-
774
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
775
-// The argument p points to a uint64 variable in which to store the value of the flag.
776
-func Uint64Var(p *uint64, names []string, value uint64, usage string) {
777
-	CommandLine.Var(newUint64Value(value, p), names, usage)
778
-}
779
-
780
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
781
-// The return value is the address of a uint64 variable that stores the value of the flag.
782
-func (fs *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 {
783
-	p := new(uint64)
784
-	fs.Uint64Var(p, names, value, usage)
785
-	return p
786
-}
787
-
788
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
789
-// The return value is the address of a uint64 variable that stores the value of the flag.
790
-func Uint64(names []string, value uint64, usage string) *uint64 {
791
-	return CommandLine.Uint64(names, value, usage)
792
-}
793
-
794
-// Uint16Var defines a uint16 flag with specified name, default value, and usage string.
795
-// The argument p points to a uint16 variable in which to store the value of the flag.
796
-func (fs *FlagSet) Uint16Var(p *uint16, names []string, value uint16, usage string) {
797
-	fs.Var(newUint16Value(value, p), names, usage)
798
-}
799
-
800
-// Uint16Var defines a uint16 flag with specified name, default value, and usage string.
801
-// The argument p points to a uint16 variable in which to store the value of the flag.
802
-func Uint16Var(p *uint16, names []string, value uint16, usage string) {
803
-	CommandLine.Var(newUint16Value(value, p), names, usage)
804
-}
805
-
806
-// Uint16 defines a uint16 flag with specified name, default value, and usage string.
807
-// The return value is the address of a uint16 variable that stores the value of the flag.
808
-func (fs *FlagSet) Uint16(names []string, value uint16, usage string) *uint16 {
809
-	p := new(uint16)
810
-	fs.Uint16Var(p, names, value, usage)
811
-	return p
812
-}
813
-
814
-// Uint16 defines a uint16 flag with specified name, default value, and usage string.
815
-// The return value is the address of a uint16 variable that stores the value of the flag.
816
-func Uint16(names []string, value uint16, usage string) *uint16 {
817
-	return CommandLine.Uint16(names, value, usage)
818
-}
819
-
820
-// StringVar defines a string flag with specified name, default value, and usage string.
821
-// The argument p points to a string variable in which to store the value of the flag.
822
-func (fs *FlagSet) StringVar(p *string, names []string, value string, usage string) {
823
-	fs.Var(newStringValue(value, p), names, usage)
824
-}
825
-
826
-// StringVar defines a string flag with specified name, default value, and usage string.
827
-// The argument p points to a string variable in which to store the value of the flag.
828
-func StringVar(p *string, names []string, value string, usage string) {
829
-	CommandLine.Var(newStringValue(value, p), names, usage)
830
-}
831
-
832
-// String defines a string flag with specified name, default value, and usage string.
833
-// The return value is the address of a string variable that stores the value of the flag.
834
-func (fs *FlagSet) String(names []string, value string, usage string) *string {
835
-	p := new(string)
836
-	fs.StringVar(p, names, value, usage)
837
-	return p
838
-}
839
-
840
-// String defines a string flag with specified name, default value, and usage string.
841
-// The return value is the address of a string variable that stores the value of the flag.
842
-func String(names []string, value string, usage string) *string {
843
-	return CommandLine.String(names, value, usage)
844
-}
845
-
846
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
847
-// The argument p points to a float64 variable in which to store the value of the flag.
848
-func (fs *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) {
849
-	fs.Var(newFloat64Value(value, p), names, usage)
850
-}
851
-
852
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
853
-// The argument p points to a float64 variable in which to store the value of the flag.
854
-func Float64Var(p *float64, names []string, value float64, usage string) {
855
-	CommandLine.Var(newFloat64Value(value, p), names, usage)
856
-}
857
-
858
-// Float64 defines a float64 flag with specified name, default value, and usage string.
859
-// The return value is the address of a float64 variable that stores the value of the flag.
860
-func (fs *FlagSet) Float64(names []string, value float64, usage string) *float64 {
861
-	p := new(float64)
862
-	fs.Float64Var(p, names, value, usage)
863
-	return p
864
-}
865
-
866
-// Float64 defines a float64 flag with specified name, default value, and usage string.
867
-// The return value is the address of a float64 variable that stores the value of the flag.
868
-func Float64(names []string, value float64, usage string) *float64 {
869
-	return CommandLine.Float64(names, value, usage)
870
-}
871
-
872
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
873
-// The argument p points to a time.Duration variable in which to store the value of the flag.
874
-func (fs *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
875
-	fs.Var(newDurationValue(value, p), names, usage)
876
-}
877
-
878
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
879
-// The argument p points to a time.Duration variable in which to store the value of the flag.
880
-func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
881
-	CommandLine.Var(newDurationValue(value, p), names, usage)
882
-}
883
-
884
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
885
-// The return value is the address of a time.Duration variable that stores the value of the flag.
886
-func (fs *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration {
887
-	p := new(time.Duration)
888
-	fs.DurationVar(p, names, value, usage)
889
-	return p
890
-}
891
-
892
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
893
-// The return value is the address of a time.Duration variable that stores the value of the flag.
894
-func Duration(names []string, value time.Duration, usage string) *time.Duration {
895
-	return CommandLine.Duration(names, value, usage)
896
-}
897
-
898
-// Var defines a flag with the specified name and usage string. The type and
899
-// value of the flag are represented by the first argument, of type Value, which
900
-// typically holds a user-defined implementation of Value. For instance, the
901
-// caller could create a flag that turns a comma-separated string into a slice
902
-// of strings by giving the slice the methods of Value; in particular, Set would
903
-// decompose the comma-separated string into the slice.
904
-func (fs *FlagSet) Var(value Value, names []string, usage string) {
905
-	// Remember the default value as a string; it won't change.
906
-	flag := &Flag{names, usage, value, value.String()}
907
-	for _, name := range names {
908
-		name = strings.TrimPrefix(name, "#")
909
-		_, alreadythere := fs.formal[name]
910
-		if alreadythere {
911
-			var msg string
912
-			if fs.name == "" {
913
-				msg = fmt.Sprintf("flag redefined: %s", name)
914
-			} else {
915
-				msg = fmt.Sprintf("%s flag redefined: %s", fs.name, name)
916
-			}
917
-			fmt.Fprintln(fs.Out(), msg)
918
-			panic(msg) // Happens only if flags are declared with identical names
919
-		}
920
-		if fs.formal == nil {
921
-			fs.formal = make(map[string]*Flag)
922
-		}
923
-		fs.formal[name] = flag
924
-	}
925
-}
926
-
927
-// Var defines a flag with the specified name and usage string. The type and
928
-// value of the flag are represented by the first argument, of type Value, which
929
-// typically holds a user-defined implementation of Value. For instance, the
930
-// caller could create a flag that turns a comma-separated string into a slice
931
-// of strings by giving the slice the methods of Value; in particular, Set would
932
-// decompose the comma-separated string into the slice.
933
-func Var(value Value, names []string, usage string) {
934
-	CommandLine.Var(value, names, usage)
935
-}
936
-
937
-// failf prints to standard error a formatted error and usage message and
938
-// returns the error.
939
-func (fs *FlagSet) failf(format string, a ...interface{}) error {
940
-	err := fmt.Errorf(format, a...)
941
-	fmt.Fprintln(fs.Out(), err)
942
-	if os.Args[0] == fs.name {
943
-		fmt.Fprintf(fs.Out(), "See '%s --help'.\n", os.Args[0])
944
-	} else {
945
-		fmt.Fprintf(fs.Out(), "See '%s %s --help'.\n", os.Args[0], fs.name)
946
-	}
947
-	return err
948
-}
949
-
950
-// usage calls the Usage method for the flag set, or the usage function if
951
-// the flag set is CommandLine.
952
-func (fs *FlagSet) usage() {
953
-	if fs == CommandLine {
954
-		Usage()
955
-	} else if fs.Usage == nil {
956
-		defaultUsage(fs)
957
-	} else {
958
-		fs.Usage()
959
-	}
960
-}
961
-
962
-func trimQuotes(str string) string {
963
-	if len(str) == 0 {
964
-		return str
965
-	}
966
-	type quote struct {
967
-		start, end byte
968
-	}
969
-
970
-	// All valid quote types.
971
-	quotes := []quote{
972
-		// Double quotes
973
-		{
974
-			start: '"',
975
-			end:   '"',
976
-		},
977
-
978
-		// Single quotes
979
-		{
980
-			start: '\'',
981
-			end:   '\'',
982
-		},
983
-	}
984
-
985
-	for _, quote := range quotes {
986
-		// Only strip if outermost match.
987
-		if str[0] == quote.start && str[len(str)-1] == quote.end {
988
-			str = str[1 : len(str)-1]
989
-			break
990
-		}
991
-	}
992
-
993
-	return str
994
-}
995
-
996
-// parseOne parses one flag. It reports whether a flag was seen.
997
-func (fs *FlagSet) parseOne() (bool, string, error) {
998
-	if len(fs.args) == 0 {
999
-		return false, "", nil
1000
-	}
1001
-	s := fs.args[0]
1002
-	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1003
-		return false, "", nil
1004
-	}
1005
-	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
1006
-		fs.args = fs.args[1:]
1007
-		return false, "", nil
1008
-	}
1009
-	name := s[1:]
1010
-	if len(name) == 0 || name[0] == '=' {
1011
-		return false, "", fs.failf("bad flag syntax: %s", s)
1012
-	}
1013
-
1014
-	// it's a flag. does it have an argument?
1015
-	fs.args = fs.args[1:]
1016
-	hasValue := false
1017
-	value := ""
1018
-	if i := strings.Index(name, "="); i != -1 {
1019
-		value = trimQuotes(name[i+1:])
1020
-		hasValue = true
1021
-		name = name[:i]
1022
-	}
1023
-
1024
-	m := fs.formal
1025
-	flag, alreadythere := m[name] // BUG
1026
-	if !alreadythere {
1027
-		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
1028
-			fs.usage()
1029
-			return false, "", ErrHelp
1030
-		}
1031
-		if len(name) > 0 && name[0] == '-' {
1032
-			return false, "", fs.failf("flag provided but not defined: -%s", name)
1033
-		}
1034
-		return false, name, ErrRetry
1035
-	}
1036
-	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
1037
-		if hasValue {
1038
-			if err := fv.Set(value); err != nil {
1039
-				return false, "", fs.failf("invalid boolean value %q for  -%s: %v", value, name, err)
1040
-			}
1041
-		} else {
1042
-			fv.Set("true")
1043
-		}
1044
-	} else {
1045
-		// It must have a value, which might be the next argument.
1046
-		if !hasValue && len(fs.args) > 0 {
1047
-			// value is the next arg
1048
-			hasValue = true
1049
-			value, fs.args = fs.args[0], fs.args[1:]
1050
-		}
1051
-		if !hasValue {
1052
-			return false, "", fs.failf("flag needs an argument: -%s", name)
1053
-		}
1054
-		if err := flag.Value.Set(value); err != nil {
1055
-			return false, "", fs.failf("invalid value %q for flag -%s: %v", value, name, err)
1056
-		}
1057
-	}
1058
-	if fs.actual == nil {
1059
-		fs.actual = make(map[string]*Flag)
1060
-	}
1061
-	fs.actual[name] = flag
1062
-	for i, n := range flag.Names {
1063
-		if n == fmt.Sprintf("#%s", name) {
1064
-			replacement := ""
1065
-			for j := i; j < len(flag.Names); j++ {
1066
-				if flag.Names[j][0] != '#' {
1067
-					replacement = flag.Names[j]
1068
-					break
1069
-				}
1070
-			}
1071
-			if replacement != "" {
1072
-				fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
1073
-			} else {
1074
-				fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
1075
-			}
1076
-		}
1077
-	}
1078
-	return true, "", nil
1079
-}
1080
-
1081
-// Parse parses flag definitions from the argument list, which should not
1082
-// include the command name.  Must be called after all flags in the FlagSet
1083
-// are defined and before flags are accessed by the program.
1084
-// The return value will be ErrHelp if -help was set but not defined.
1085
-func (fs *FlagSet) Parse(arguments []string) error {
1086
-	fs.parsed = true
1087
-	fs.args = arguments
1088
-	for {
1089
-		seen, name, err := fs.parseOne()
1090
-		if seen {
1091
-			continue
1092
-		}
1093
-		if err == nil {
1094
-			break
1095
-		}
1096
-		if err == ErrRetry {
1097
-			if len(name) > 1 {
1098
-				err = nil
1099
-				for _, letter := range strings.Split(name, "") {
1100
-					fs.args = append([]string{"-" + letter}, fs.args...)
1101
-					seen2, _, err2 := fs.parseOne()
1102
-					if seen2 {
1103
-						continue
1104
-					}
1105
-					if err2 != nil {
1106
-						err = fs.failf("flag provided but not defined: -%s", name)
1107
-						break
1108
-					}
1109
-				}
1110
-				if err == nil {
1111
-					continue
1112
-				}
1113
-			} else {
1114
-				err = fs.failf("flag provided but not defined: -%s", name)
1115
-			}
1116
-		}
1117
-		switch fs.errorHandling {
1118
-		case ContinueOnError:
1119
-			return err
1120
-		case ExitOnError:
1121
-			os.Exit(125)
1122
-		case PanicOnError:
1123
-			panic(err)
1124
-		}
1125
-	}
1126
-	return nil
1127
-}
1128
-
1129
-// ParseFlags is a utility function that adds a help flag if withHelp is true,
1130
-// calls fs.Parse(args) and prints a relevant error message if there are
1131
-// incorrect number of arguments. It returns error only if error handling is
1132
-// set to ContinueOnError and parsing fails. If error handling is set to
1133
-// ExitOnError, it's safe to ignore the return value.
1134
-func (fs *FlagSet) ParseFlags(args []string, withHelp bool) error {
1135
-	var help *bool
1136
-	if withHelp {
1137
-		help = fs.Bool([]string{"#help", "-help"}, false, "Print usage")
1138
-	}
1139
-	if err := fs.Parse(args); err != nil {
1140
-		return err
1141
-	}
1142
-	if help != nil && *help {
1143
-		fs.SetOutput(os.Stdout)
1144
-		fs.Usage()
1145
-		os.Exit(0)
1146
-	}
1147
-	if str := fs.CheckArgs(); str != "" {
1148
-		fs.SetOutput(os.Stderr)
1149
-		fs.ReportError(str, withHelp)
1150
-		fs.ShortUsage()
1151
-		os.Exit(1)
1152
-	}
1153
-	return nil
1154
-}
1155
-
1156
-// ReportError is a utility method that prints a user-friendly message
1157
-// containing the error that occurred during parsing and a suggestion to get help
1158
-func (fs *FlagSet) ReportError(str string, withHelp bool) {
1159
-	if withHelp {
1160
-		if os.Args[0] == fs.Name() {
1161
-			str += ".\nSee '" + os.Args[0] + " --help'"
1162
-		} else {
1163
-			str += ".\nSee '" + os.Args[0] + " " + fs.Name() + " --help'"
1164
-		}
1165
-	}
1166
-	fmt.Fprintf(fs.Out(), "%s: %s.\n", os.Args[0], str)
1167
-}
1168
-
1169
-// Parsed reports whether fs.Parse has been called.
1170
-func (fs *FlagSet) Parsed() bool {
1171
-	return fs.parsed
1172
-}
1173
-
1174
-// Parse parses the command-line flags from os.Args[1:].  Must be called
1175
-// after all flags are defined and before flags are accessed by the program.
1176
-func Parse() {
1177
-	// Ignore errors; CommandLine is set for ExitOnError.
1178
-	CommandLine.Parse(os.Args[1:])
1179
-}
1180
-
1181
-// Parsed returns true if the command-line flags have been parsed.
1182
-func Parsed() bool {
1183
-	return CommandLine.Parsed()
1184
-}
1185
-
1186
-// CommandLine is the default set of command-line flags, parsed from os.Args.
1187
-// The top-level functions such as BoolVar, Arg, and on are wrappers for the
1188
-// methods of CommandLine.
1189
-var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1190
-
1191
-// NewFlagSet returns a new, empty flag set with the specified name and
1192
-// error handling property.
1193
-func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1194
-	f := &FlagSet{
1195
-		name:          name,
1196
-		errorHandling: errorHandling,
1197
-	}
1198
-	return f
1199
-}
1200
-
1201
-// Init sets the name and error handling property for a flag set.
1202
-// By default, the zero FlagSet uses an empty name and the
1203
-// ContinueOnError error handling policy.
1204
-func (fs *FlagSet) Init(name string, errorHandling ErrorHandling) {
1205
-	fs.name = name
1206
-	fs.errorHandling = errorHandling
1207
-}
1208
-
1209
-type mergeVal struct {
1210
-	Value
1211
-	key  string
1212
-	fset *FlagSet
1213
-}
1214
-
1215
-func (v mergeVal) Set(s string) error {
1216
-	return v.fset.Set(v.key, s)
1217
-}
1218
-
1219
-func (v mergeVal) IsBoolFlag() bool {
1220
-	if b, ok := v.Value.(boolFlag); ok {
1221
-		return b.IsBoolFlag()
1222
-	}
1223
-	return false
1224
-}
1225
-
1226
-// Name returns the name of a mergeVal.
1227
-// If the original value had a name, return the original name,
1228
-// otherwise, return the key asinged to this mergeVal.
1229
-func (v mergeVal) Name() string {
1230
-	type namedValue interface {
1231
-		Name() string
1232
-	}
1233
-	if nVal, ok := v.Value.(namedValue); ok {
1234
-		return nVal.Name()
1235
-	}
1236
-	return v.key
1237
-}
1238
-
1239
-// Merge is a helper function that merges n FlagSets into a single dest FlagSet
1240
-// In case of name collision between the flagsets it will apply
1241
-// the destination FlagSet's errorHandling behavior.
1242
-func Merge(dest *FlagSet, flagsets ...*FlagSet) error {
1243
-	for _, fset := range flagsets {
1244
-		if fset.formal == nil {
1245
-			continue
1246
-		}
1247
-		for k, f := range fset.formal {
1248
-			if _, ok := dest.formal[k]; ok {
1249
-				var err error
1250
-				if fset.name == "" {
1251
-					err = fmt.Errorf("flag redefined: %s", k)
1252
-				} else {
1253
-					err = fmt.Errorf("%s flag redefined: %s", fset.name, k)
1254
-				}
1255
-				fmt.Fprintln(fset.Out(), err.Error())
1256
-				// Happens only if flags are declared with identical names
1257
-				switch dest.errorHandling {
1258
-				case ContinueOnError:
1259
-					return err
1260
-				case ExitOnError:
1261
-					os.Exit(2)
1262
-				case PanicOnError:
1263
-					panic(err)
1264
-				}
1265
-			}
1266
-			newF := *f
1267
-			newF.Value = mergeVal{f.Value, k, fset}
1268
-			if dest.formal == nil {
1269
-				dest.formal = make(map[string]*Flag)
1270
-			}
1271
-			dest.formal[k] = &newF
1272
-		}
1273
-	}
1274
-	return nil
1275
-}
1276
-
1277
-// IsEmpty reports if the FlagSet is actually empty.
1278
-func (fs *FlagSet) IsEmpty() bool {
1279
-	return len(fs.actual) == 0
1280
-}
1281 1
deleted file mode 100644
... ...
@@ -1,527 +0,0 @@
1
-// Copyright 2014-2016 The Docker & Go Authors. All rights reserved.
2
-// Use of this source code is governed by a BSD-style
3
-// license that can be found in the LICENSE file.
4
-
5
-package mflag
6
-
7
-import (
8
-	"bytes"
9
-	"fmt"
10
-	"os"
11
-	"sort"
12
-	"strings"
13
-	"testing"
14
-	"time"
15
-)
16
-
17
-// ResetForTesting clears all flag state and sets the usage function as directed.
18
-// After calling ResetForTesting, parse errors in flag handling will not
19
-// exit the program.
20
-func ResetForTesting(usage func()) {
21
-	CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
22
-	Usage = usage
23
-}
24
-func boolString(s string) string {
25
-	if s == "0" {
26
-		return "false"
27
-	}
28
-	return "true"
29
-}
30
-
31
-func TestEverything(t *testing.T) {
32
-	ResetForTesting(nil)
33
-	Bool([]string{"test_bool"}, false, "bool value")
34
-	Int([]string{"test_int"}, 0, "int value")
35
-	Int64([]string{"test_int64"}, 0, "int64 value")
36
-	Uint([]string{"test_uint"}, 0, "uint value")
37
-	Uint64([]string{"test_uint64"}, 0, "uint64 value")
38
-	String([]string{"test_string"}, "0", "string value")
39
-	Float64([]string{"test_float64"}, 0, "float64 value")
40
-	Duration([]string{"test_duration"}, 0, "time.Duration value")
41
-
42
-	m := make(map[string]*Flag)
43
-	desired := "0"
44
-	visitor := func(f *Flag) {
45
-		for _, name := range f.Names {
46
-			if len(name) > 5 && name[0:5] == "test_" {
47
-				m[name] = f
48
-				ok := false
49
-				switch {
50
-				case f.Value.String() == desired:
51
-					ok = true
52
-				case name == "test_bool" && f.Value.String() == boolString(desired):
53
-					ok = true
54
-				case name == "test_duration" && f.Value.String() == desired+"s":
55
-					ok = true
56
-				}
57
-				if !ok {
58
-					t.Error("Visit: bad value", f.Value.String(), "for", name)
59
-				}
60
-			}
61
-		}
62
-	}
63
-	VisitAll(visitor)
64
-	if len(m) != 8 {
65
-		t.Error("VisitAll misses some flags")
66
-		for k, v := range m {
67
-			t.Log(k, *v)
68
-		}
69
-	}
70
-	m = make(map[string]*Flag)
71
-	Visit(visitor)
72
-	if len(m) != 0 {
73
-		t.Errorf("Visit sees unset flags")
74
-		for k, v := range m {
75
-			t.Log(k, *v)
76
-		}
77
-	}
78
-	// Now set all flags
79
-	Set("test_bool", "true")
80
-	Set("test_int", "1")
81
-	Set("test_int64", "1")
82
-	Set("test_uint", "1")
83
-	Set("test_uint64", "1")
84
-	Set("test_string", "1")
85
-	Set("test_float64", "1")
86
-	Set("test_duration", "1s")
87
-	desired = "1"
88
-	Visit(visitor)
89
-	if len(m) != 8 {
90
-		t.Error("Visit fails after set")
91
-		for k, v := range m {
92
-			t.Log(k, *v)
93
-		}
94
-	}
95
-	// Now test they're visited in sort order.
96
-	var flagNames []string
97
-	Visit(func(f *Flag) {
98
-		for _, name := range f.Names {
99
-			flagNames = append(flagNames, name)
100
-		}
101
-	})
102
-	if !sort.StringsAreSorted(flagNames) {
103
-		t.Errorf("flag names not sorted: %v", flagNames)
104
-	}
105
-}
106
-
107
-func TestGet(t *testing.T) {
108
-	ResetForTesting(nil)
109
-	Bool([]string{"test_bool"}, true, "bool value")
110
-	Int([]string{"test_int"}, 1, "int value")
111
-	Int64([]string{"test_int64"}, 2, "int64 value")
112
-	Uint([]string{"test_uint"}, 3, "uint value")
113
-	Uint64([]string{"test_uint64"}, 4, "uint64 value")
114
-	String([]string{"test_string"}, "5", "string value")
115
-	Float64([]string{"test_float64"}, 6, "float64 value")
116
-	Duration([]string{"test_duration"}, 7, "time.Duration value")
117
-
118
-	visitor := func(f *Flag) {
119
-		for _, name := range f.Names {
120
-			if len(name) > 5 && name[0:5] == "test_" {
121
-				g, ok := f.Value.(Getter)
122
-				if !ok {
123
-					t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
124
-					return
125
-				}
126
-				switch name {
127
-				case "test_bool":
128
-					ok = g.Get() == true
129
-				case "test_int":
130
-					ok = g.Get() == int(1)
131
-				case "test_int64":
132
-					ok = g.Get() == int64(2)
133
-				case "test_uint":
134
-					ok = g.Get() == uint(3)
135
-				case "test_uint64":
136
-					ok = g.Get() == uint64(4)
137
-				case "test_string":
138
-					ok = g.Get() == "5"
139
-				case "test_float64":
140
-					ok = g.Get() == float64(6)
141
-				case "test_duration":
142
-					ok = g.Get() == time.Duration(7)
143
-				}
144
-				if !ok {
145
-					t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), name)
146
-				}
147
-			}
148
-		}
149
-	}
150
-	VisitAll(visitor)
151
-}
152
-
153
-func testParse(f *FlagSet, t *testing.T) {
154
-	if f.Parsed() {
155
-		t.Error("f.Parse() = true before Parse")
156
-	}
157
-	boolFlag := f.Bool([]string{"bool"}, false, "bool value")
158
-	bool2Flag := f.Bool([]string{"bool2"}, false, "bool2 value")
159
-	f.Bool([]string{"bool3"}, false, "bool3 value")
160
-	bool4Flag := f.Bool([]string{"bool4"}, false, "bool4 value")
161
-	intFlag := f.Int([]string{"-int"}, 0, "int value")
162
-	int64Flag := f.Int64([]string{"-int64"}, 0, "int64 value")
163
-	uintFlag := f.Uint([]string{"uint"}, 0, "uint value")
164
-	uint64Flag := f.Uint64([]string{"-uint64"}, 0, "uint64 value")
165
-	stringFlag := f.String([]string{"string"}, "0", "string value")
166
-	f.String([]string{"string2"}, "0", "string2 value")
167
-	singleQuoteFlag := f.String([]string{"squote"}, "", "single quoted value")
168
-	doubleQuoteFlag := f.String([]string{"dquote"}, "", "double quoted value")
169
-	mixedQuoteFlag := f.String([]string{"mquote"}, "", "mixed quoted value")
170
-	mixed2QuoteFlag := f.String([]string{"mquote2"}, "", "mixed2 quoted value")
171
-	nestedQuoteFlag := f.String([]string{"nquote"}, "", "nested quoted value")
172
-	nested2QuoteFlag := f.String([]string{"nquote2"}, "", "nested2 quoted value")
173
-	float64Flag := f.Float64([]string{"float64"}, 0, "float64 value")
174
-	durationFlag := f.Duration([]string{"duration"}, 5*time.Second, "time.Duration value")
175
-	extra := "one-extra-argument"
176
-	args := []string{
177
-		"-bool",
178
-		"-bool2=true",
179
-		"-bool4=false",
180
-		"--int", "22",
181
-		"--int64", "0x23",
182
-		"-uint", "24",
183
-		"--uint64", "25",
184
-		"-string", "hello",
185
-		"-squote='single'",
186
-		`-dquote="double"`,
187
-		`-mquote='mixed"`,
188
-		`-mquote2="mixed2'`,
189
-		`-nquote="'single nested'"`,
190
-		`-nquote2='"double nested"'`,
191
-		"-float64", "2718e28",
192
-		"-duration", "2m",
193
-		extra,
194
-	}
195
-	if err := f.Parse(args); err != nil {
196
-		t.Fatal(err)
197
-	}
198
-	if !f.Parsed() {
199
-		t.Error("f.Parse() = false after Parse")
200
-	}
201
-	if *boolFlag != true {
202
-		t.Error("bool flag should be true, is ", *boolFlag)
203
-	}
204
-	if *bool2Flag != true {
205
-		t.Error("bool2 flag should be true, is ", *bool2Flag)
206
-	}
207
-	if !f.IsSet("bool2") {
208
-		t.Error("bool2 should be marked as set")
209
-	}
210
-	if f.IsSet("bool3") {
211
-		t.Error("bool3 should not be marked as set")
212
-	}
213
-	if !f.IsSet("bool4") {
214
-		t.Error("bool4 should be marked as set")
215
-	}
216
-	if *bool4Flag != false {
217
-		t.Error("bool4 flag should be false, is ", *bool4Flag)
218
-	}
219
-	if *intFlag != 22 {
220
-		t.Error("int flag should be 22, is ", *intFlag)
221
-	}
222
-	if *int64Flag != 0x23 {
223
-		t.Error("int64 flag should be 0x23, is ", *int64Flag)
224
-	}
225
-	if *uintFlag != 24 {
226
-		t.Error("uint flag should be 24, is ", *uintFlag)
227
-	}
228
-	if *uint64Flag != 25 {
229
-		t.Error("uint64 flag should be 25, is ", *uint64Flag)
230
-	}
231
-	if *stringFlag != "hello" {
232
-		t.Error("string flag should be `hello`, is ", *stringFlag)
233
-	}
234
-	if !f.IsSet("string") {
235
-		t.Error("string flag should be marked as set")
236
-	}
237
-	if f.IsSet("string2") {
238
-		t.Error("string2 flag should not be marked as set")
239
-	}
240
-	if *singleQuoteFlag != "single" {
241
-		t.Error("single quote string flag should be `single`, is ", *singleQuoteFlag)
242
-	}
243
-	if *doubleQuoteFlag != "double" {
244
-		t.Error("double quote string flag should be `double`, is ", *doubleQuoteFlag)
245
-	}
246
-	if *mixedQuoteFlag != `'mixed"` {
247
-		t.Error("mixed quote string flag should be `'mixed\"`, is ", *mixedQuoteFlag)
248
-	}
249
-	if *mixed2QuoteFlag != `"mixed2'` {
250
-		t.Error("mixed2 quote string flag should be `\"mixed2'`, is ", *mixed2QuoteFlag)
251
-	}
252
-	if *nestedQuoteFlag != "'single nested'" {
253
-		t.Error("nested quote string flag should be `'single nested'`, is ", *nestedQuoteFlag)
254
-	}
255
-	if *nested2QuoteFlag != `"double nested"` {
256
-		t.Error("double quote string flag should be `\"double nested\"`, is ", *nested2QuoteFlag)
257
-	}
258
-	if *float64Flag != 2718e28 {
259
-		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
260
-	}
261
-	if *durationFlag != 2*time.Minute {
262
-		t.Error("duration flag should be 2m, is ", *durationFlag)
263
-	}
264
-	if len(f.Args()) != 1 {
265
-		t.Error("expected one argument, got", len(f.Args()))
266
-	} else if f.Args()[0] != extra {
267
-		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
268
-	}
269
-}
270
-
271
-func testPanic(f *FlagSet, t *testing.T) {
272
-	f.Int([]string{"-int"}, 0, "int value")
273
-	if f.Parsed() {
274
-		t.Error("f.Parse() = true before Parse")
275
-	}
276
-	args := []string{
277
-		"-int", "21",
278
-	}
279
-	f.Parse(args)
280
-}
281
-
282
-func TestParsePanic(t *testing.T) {
283
-	ResetForTesting(func() {})
284
-	testPanic(CommandLine, t)
285
-}
286
-
287
-func TestParse(t *testing.T) {
288
-	ResetForTesting(func() { t.Error("bad parse") })
289
-	testParse(CommandLine, t)
290
-}
291
-
292
-func TestFlagSetParse(t *testing.T) {
293
-	testParse(NewFlagSet("test", ContinueOnError), t)
294
-}
295
-
296
-// Declare a user-defined flag type.
297
-type flagVar []string
298
-
299
-func (f *flagVar) String() string {
300
-	return fmt.Sprint([]string(*f))
301
-}
302
-
303
-func (f *flagVar) Set(value string) error {
304
-	*f = append(*f, value)
305
-	return nil
306
-}
307
-
308
-func TestUserDefined(t *testing.T) {
309
-	var flags FlagSet
310
-	flags.Init("test", ContinueOnError)
311
-	var v flagVar
312
-	flags.Var(&v, []string{"v"}, "usage")
313
-	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
314
-		t.Error(err)
315
-	}
316
-	if len(v) != 3 {
317
-		t.Fatal("expected 3 args; got ", len(v))
318
-	}
319
-	expect := "[1 2 3]"
320
-	if v.String() != expect {
321
-		t.Errorf("expected value %q got %q", expect, v.String())
322
-	}
323
-}
324
-
325
-// Declare a user-defined boolean flag type.
326
-type boolFlagVar struct {
327
-	count int
328
-}
329
-
330
-func (b *boolFlagVar) String() string {
331
-	return fmt.Sprintf("%d", b.count)
332
-}
333
-
334
-func (b *boolFlagVar) Set(value string) error {
335
-	if value == "true" {
336
-		b.count++
337
-	}
338
-	return nil
339
-}
340
-
341
-func (b *boolFlagVar) IsBoolFlag() bool {
342
-	return b.count < 4
343
-}
344
-
345
-func TestUserDefinedBool(t *testing.T) {
346
-	var flags FlagSet
347
-	flags.Init("test", ContinueOnError)
348
-	var b boolFlagVar
349
-	var err error
350
-	flags.Var(&b, []string{"b"}, "usage")
351
-	if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
352
-		if b.count < 4 {
353
-			t.Error(err)
354
-		}
355
-	}
356
-
357
-	if b.count != 4 {
358
-		t.Errorf("want: %d; got: %d", 4, b.count)
359
-	}
360
-
361
-	if err == nil {
362
-		t.Error("expected error; got none")
363
-	}
364
-}
365
-
366
-func TestSetOutput(t *testing.T) {
367
-	var flags FlagSet
368
-	var buf bytes.Buffer
369
-	flags.SetOutput(&buf)
370
-	flags.Init("test", ContinueOnError)
371
-	flags.Parse([]string{"-unknown"})
372
-	if out := buf.String(); !strings.Contains(out, "-unknown") {
373
-		t.Logf("expected output mentioning unknown; got %q", out)
374
-	}
375
-}
376
-
377
-// This tests that one can reset the flags. This still works but not well, and is
378
-// superseded by FlagSet.
379
-func TestChangingArgs(t *testing.T) {
380
-	ResetForTesting(func() { t.Fatal("bad parse") })
381
-	oldArgs := os.Args
382
-	defer func() { os.Args = oldArgs }()
383
-	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
384
-	before := Bool([]string{"before"}, false, "")
385
-	if err := CommandLine.Parse(os.Args[1:]); err != nil {
386
-		t.Fatal(err)
387
-	}
388
-	cmd := Arg(0)
389
-	os.Args = Args()
390
-	after := Bool([]string{"after"}, false, "")
391
-	Parse()
392
-	args := Args()
393
-
394
-	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
395
-		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
396
-	}
397
-}
398
-
399
-// Test that -help invokes the usage message and returns ErrHelp.
400
-func TestHelp(t *testing.T) {
401
-	var helpCalled = false
402
-	fs := NewFlagSet("help test", ContinueOnError)
403
-	fs.Usage = func() { helpCalled = true }
404
-	var flag bool
405
-	fs.BoolVar(&flag, []string{"flag"}, false, "regular flag")
406
-	// Regular flag invocation should work
407
-	err := fs.Parse([]string{"-flag=true"})
408
-	if err != nil {
409
-		t.Fatal("expected no error; got ", err)
410
-	}
411
-	if !flag {
412
-		t.Error("flag was not set by -flag")
413
-	}
414
-	if helpCalled {
415
-		t.Error("help called for regular flag")
416
-		helpCalled = false // reset for next test
417
-	}
418
-	// Help flag should work as expected.
419
-	err = fs.Parse([]string{"-help"})
420
-	if err == nil {
421
-		t.Fatal("error expected")
422
-	}
423
-	if err != ErrHelp {
424
-		t.Fatal("expected ErrHelp; got ", err)
425
-	}
426
-	if !helpCalled {
427
-		t.Fatal("help was not called")
428
-	}
429
-	// If we define a help flag, that should override.
430
-	var help bool
431
-	fs.BoolVar(&help, []string{"help"}, false, "help flag")
432
-	helpCalled = false
433
-	err = fs.Parse([]string{"-help"})
434
-	if err != nil {
435
-		t.Fatal("expected no error for defined -help; got ", err)
436
-	}
437
-	if helpCalled {
438
-		t.Fatal("help was called; should not have been for defined help flag")
439
-	}
440
-}
441
-
442
-// Test the flag count functions.
443
-func TestFlagCounts(t *testing.T) {
444
-	fs := NewFlagSet("help test", ContinueOnError)
445
-	var flag bool
446
-	fs.BoolVar(&flag, []string{"flag1"}, false, "regular flag")
447
-	fs.BoolVar(&flag, []string{"#deprecated1"}, false, "regular flag")
448
-	fs.BoolVar(&flag, []string{"f", "flag2"}, false, "regular flag")
449
-	fs.BoolVar(&flag, []string{"#d", "#deprecated2"}, false, "regular flag")
450
-	fs.BoolVar(&flag, []string{"flag3"}, false, "regular flag")
451
-	fs.BoolVar(&flag, []string{"g", "#flag4", "-flag4"}, false, "regular flag")
452
-
453
-	if fs.FlagCount() != 6 {
454
-		t.Fatal("FlagCount wrong. ", fs.FlagCount())
455
-	}
456
-	if fs.FlagCountUndeprecated() != 4 {
457
-		t.Fatal("FlagCountUndeprecated wrong. ", fs.FlagCountUndeprecated())
458
-	}
459
-	if fs.NFlag() != 0 {
460
-		t.Fatal("NFlag wrong. ", fs.NFlag())
461
-	}
462
-	err := fs.Parse([]string{"-fd", "-g", "-flag4"})
463
-	if err != nil {
464
-		t.Fatal("expected no error for defined -help; got ", err)
465
-	}
466
-	if fs.NFlag() != 4 {
467
-		t.Fatal("NFlag wrong. ", fs.NFlag())
468
-	}
469
-}
470
-
471
-// Show up bug in sortFlags
472
-func TestSortFlags(t *testing.T) {
473
-	fs := NewFlagSet("help TestSortFlags", ContinueOnError)
474
-
475
-	var err error
476
-
477
-	var b bool
478
-	fs.BoolVar(&b, []string{"b", "-banana"}, false, "usage")
479
-
480
-	err = fs.Parse([]string{"--banana=true"})
481
-	if err != nil {
482
-		t.Fatal("expected no error; got ", err)
483
-	}
484
-
485
-	count := 0
486
-
487
-	fs.VisitAll(func(flag *Flag) {
488
-		count++
489
-		if flag == nil {
490
-			t.Fatal("VisitAll should not return a nil flag")
491
-		}
492
-	})
493
-	flagcount := fs.FlagCount()
494
-	if flagcount != count {
495
-		t.Fatalf("FlagCount (%d) != number (%d) of elements visited", flagcount, count)
496
-	}
497
-	// Make sure its idempotent
498
-	if flagcount != fs.FlagCount() {
499
-		t.Fatalf("FlagCount (%d) != fs.FlagCount() (%d) of elements visited", flagcount, fs.FlagCount())
500
-	}
501
-
502
-	count = 0
503
-	fs.Visit(func(flag *Flag) {
504
-		count++
505
-		if flag == nil {
506
-			t.Fatal("Visit should not return a nil flag")
507
-		}
508
-	})
509
-	nflag := fs.NFlag()
510
-	if nflag != count {
511
-		t.Fatalf("NFlag (%d) != number (%d) of elements visited", nflag, count)
512
-	}
513
-	if nflag != fs.NFlag() {
514
-		t.Fatalf("NFlag (%d) != fs.NFlag() (%d) of elements visited", nflag, fs.NFlag())
515
-	}
516
-}
517
-
518
-func TestMergeFlags(t *testing.T) {
519
-	base := NewFlagSet("base", ContinueOnError)
520
-	base.String([]string{"f"}, "", "")
521
-
522
-	fs := NewFlagSet("test", ContinueOnError)
523
-	Merge(fs, base)
524
-	if len(fs.formal) != 1 {
525
-		t.Fatalf("FlagCount (%d) != number (1) of elements merged", len(fs.formal))
526
-	}
527
-}
... ...
@@ -3,7 +3,7 @@
3 3
 package registry
4 4
 
5 5
 import (
6
-	flag "github.com/docker/docker/pkg/mflag"
6
+	"github.com/spf13/pflag"
7 7
 )
8 8
 
9 9
 var (
... ...
@@ -20,6 +20,6 @@ func cleanPath(s string) string {
20 20
 }
21 21
 
22 22
 // installCliPlatformFlags handles any platform specific flags for the service.
23
-func (options *ServiceOptions) installCliPlatformFlags(flags *flag.FlagSet) string) {
23
+func (options *ServiceOptions) installCliPlatformFlags(flags *pflag.FlagSet) {
24 24
 	flags.BoolVar(&options.V2Only, "disable-legacy-registry", false, "Disable contacting legacy registries")
25 25
 }
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"path/filepath"
6 6
 	"strings"
7 7
 
8
-	flag "github.com/docker/docker/pkg/mflag"
8
+	"github.com/spf13/pflag"
9 9
 )
10 10
 
11 11
 // CertsDir is the directory where certificates are stored
... ...
@@ -20,6 +20,6 @@ func cleanPath(s string) string {
20 20
 }
21 21
 
22 22
 // installCliPlatformFlags handles any platform specific flags for the service.
23
-func (options *ServiceOptions) installCliPlatformFlags(flags *flag.FlagSet) string) {
23
+func (options *ServiceOptions) installCliPlatformFlags(flags *pflag.FlagSet) {
24 24
 	// No Windows specific flags.
25 25
 }