Browse code

refactor redundant code around calls to cmd.Parse

Signed-off-by: Tibor Vass <teabee89@gmail.com>

Tibor Vass authored on 2014/11/06 01:57:51
Showing 5 changed files
... ...
@@ -85,18 +85,11 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
85 85
 	rm := cmd.Bool([]string{"#rm", "-rm"}, true, "Remove intermediate containers after a successful build")
86 86
 	forceRm := cmd.Bool([]string{"-force-rm"}, false, "Always remove intermediate containers, even after unsuccessful builds")
87 87
 	pull := cmd.Bool([]string{"-pull"}, false, "Always attempt to pull a newer version of the image")
88
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
88
+	cmd.Require(flag.Exact, 1)
89 89
 
90
-	if err := cmd.Parse(args); err != nil {
90
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
91 91
 		return nil
92 92
 	}
93
-	if *help {
94
-		cmd.Usage()
95
-		return nil
96
-	}
97
-	if cmd.BadArgs(flag.Exact, 1) {
98
-		os.Exit(1)
99
-	}
100 93
 
101 94
 	var (
102 95
 		context  archive.Archive
... ...
@@ -255,22 +248,18 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
255 255
 // 'docker login': login / register a user to registry service.
256 256
 func (cli *DockerCli) CmdLogin(args ...string) error {
257 257
 	cmd := cli.Subcmd("login", "[SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
258
+	cmd.Require(flag.Max, 1)
258 259
 
259 260
 	var username, password, email string
260 261
 
261 262
 	cmd.StringVar(&username, []string{"u", "-username"}, "", "Username")
262 263
 	cmd.StringVar(&password, []string{"p", "-password"}, "", "Password")
263 264
 	cmd.StringVar(&email, []string{"e", "-email"}, "", "Email")
264
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
265 265
 
266
-	err := cmd.Parse(args)
267
-	if err != nil {
268
-		return nil
269
-	}
270
-	if *help {
271
-		cmd.Usage()
266
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
272 267
 		return nil
273 268
 	}
269
+
274 270
 	serverAddress := registry.IndexServerAddress()
275 271
 	if len(cmd.Args()) > 0 {
276 272
 		serverAddress = cmd.Arg(0)
... ...
@@ -377,8 +366,9 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
377 377
 // log out from a Docker registry
378 378
 func (cli *DockerCli) CmdLogout(args ...string) error {
379 379
 	cmd := cli.Subcmd("logout", "[SERVER]", "Log out from a Docker registry, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
380
+	cmd.Require(flag.Max, 1)
380 381
 
381
-	if err := cmd.Parse(args); err != nil {
382
+	if err := utils.ParseFlags(cmd, args, false); err != nil {
382 383
 		return nil
383 384
 	}
384 385
 	serverAddress := registry.IndexServerAddress()
... ...
@@ -403,18 +393,12 @@ func (cli *DockerCli) CmdLogout(args ...string) error {
403 403
 // 'docker wait': block until a container stops
404 404
 func (cli *DockerCli) CmdWait(args ...string) error {
405 405
 	cmd := cli.Subcmd("wait", "CONTAINER [CONTAINER...]", "Block until a container stops, then print its exit code.")
406
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
406
+	cmd.Require(flag.Min, 1)
407 407
 
408
-	if err := cmd.Parse(args); err != nil {
408
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
409 409
 		return nil
410 410
 	}
411
-	if *help {
412
-		cmd.Usage()
413
-		return nil
414
-	}
415
-	if cmd.BadArgs(flag.Min, 1) {
416
-		os.Exit(1)
417
-	}
411
+
418 412
 	var encounteredError error
419 413
 	for _, name := range cmd.Args() {
420 414
 		status, err := waitForExit(cli, name)
... ...
@@ -431,12 +415,12 @@ func (cli *DockerCli) CmdWait(args ...string) error {
431 431
 // 'docker version': show version information
432 432
 func (cli *DockerCli) CmdVersion(args ...string) error {
433 433
 	cmd := cli.Subcmd("version", "", "Show the Docker version information.")
434
-	if err := cmd.Parse(args); err != nil {
434
+	cmd.Require(flag.Exact, 0)
435
+
436
+	if err := utils.ParseFlags(cmd, args, false); err != nil {
435 437
 		return nil
436 438
 	}
437
-	if cmd.BadArgs(flag.Exact, 0) {
438
-		os.Exit(1)
439
-	}
439
+
440 440
 	if dockerversion.VERSION != "" {
441 441
 		fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION)
442 442
 	}
... ...
@@ -475,12 +459,10 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
475 475
 // 'docker info': display system-wide information.
476 476
 func (cli *DockerCli) CmdInfo(args ...string) error {
477 477
 	cmd := cli.Subcmd("info", "", "Display system-wide information")
478
-	if err := cmd.Parse(args); err != nil {
478
+	cmd.Require(flag.Exact, 0)
479
+	if err := utils.ParseFlags(cmd, args, false); err != nil {
479 480
 		return nil
480 481
 	}
481
-	if cmd.BadArgs(flag.Exact, 0) {
482
-		os.Exit(1)
483
-	}
484 482
 
485 483
 	body, _, err := readBody(cli.call("GET", "/info", nil, false))
486 484
 	if err != nil {
... ...
@@ -594,18 +576,11 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
594 594
 func (cli *DockerCli) CmdStop(args ...string) error {
595 595
 	cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period")
596 596
 	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.")
597
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
597
+	cmd.Require(flag.Min, 1)
598 598
 
599
-	if err := cmd.Parse(args); err != nil {
600
-		return nil
601
-	}
602
-	if *help {
603
-		cmd.Usage()
599
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
604 600
 		return nil
605 601
 	}
606
-	if cmd.BadArgs(flag.Min, 1) {
607
-		os.Exit(1)
608
-	}
609 602
 
610 603
 	v := url.Values{}
611 604
 	v.Set("t", strconv.Itoa(*nSeconds))
... ...
@@ -626,18 +601,11 @@ func (cli *DockerCli) CmdStop(args ...string) error {
626 626
 func (cli *DockerCli) CmdRestart(args ...string) error {
627 627
 	cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container")
628 628
 	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default is 10 seconds.")
629
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
629
+	cmd.Require(flag.Min, 1)
630 630
 
631
-	if err := cmd.Parse(args); err != nil {
632
-		return nil
633
-	}
634
-	if *help {
635
-		cmd.Usage()
631
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
636 632
 		return nil
637 633
 	}
638
-	if cmd.BadArgs(flag.Min, 1) {
639
-		os.Exit(1)
640
-	}
641 634
 
642 635
 	v := url.Values{}
643 636
 	v.Set("t", strconv.Itoa(*nSeconds))
... ...
@@ -689,19 +657,12 @@ func (cli *DockerCli) CmdStart(args ...string) error {
689 689
 		cmd       = cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container")
690 690
 		attach    = cmd.Bool([]string{"a", "-attach"}, false, "Attach container's STDOUT and STDERR and forward all signals to the process")
691 691
 		openStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's STDIN")
692
-		help      = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
693 692
 	)
694 693
 
695
-	if err := cmd.Parse(args); err != nil {
696
-		return nil
697
-	}
698
-	if *help {
699
-		cmd.Usage()
694
+	cmd.Require(flag.Min, 1)
695
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
700 696
 		return nil
701 697
 	}
702
-	if cmd.BadArgs(flag.Min, 1) {
703
-		os.Exit(1)
704
-	}
705 698
 
706 699
 	hijacked := make(chan io.Closer)
707 700
 
... ...
@@ -804,12 +765,10 @@ func (cli *DockerCli) CmdStart(args ...string) error {
804 804
 
805 805
 func (cli *DockerCli) CmdUnpause(args ...string) error {
806 806
 	cmd := cli.Subcmd("unpause", "CONTAINER", "Unpause all processes within a container")
807
-	if err := cmd.Parse(args); err != nil {
807
+	cmd.Require(flag.Exact, 1)
808
+	if err := utils.ParseFlags(cmd, args, false); err != nil {
808 809
 		return nil
809 810
 	}
810
-	if cmd.BadArgs(flag.Exact, 1) {
811
-		os.Exit(1)
812
-	}
813 811
 
814 812
 	var encounteredError error
815 813
 	for _, name := range cmd.Args() {
... ...
@@ -825,12 +784,10 @@ func (cli *DockerCli) CmdUnpause(args ...string) error {
825 825
 
826 826
 func (cli *DockerCli) CmdPause(args ...string) error {
827 827
 	cmd := cli.Subcmd("pause", "CONTAINER", "Pause all processes within a container")
828
-	if err := cmd.Parse(args); err != nil {
828
+	cmd.Require(flag.Exact, 1)
829
+	if err := utils.ParseFlags(cmd, args, false); err != nil {
829 830
 		return nil
830 831
 	}
831
-	if cmd.BadArgs(flag.Exact, 1) {
832
-		os.Exit(1)
833
-	}
834 832
 
835 833
 	var encounteredError error
836 834
 	for _, name := range cmd.Args() {
... ...
@@ -847,18 +804,11 @@ func (cli *DockerCli) CmdPause(args ...string) error {
847 847
 func (cli *DockerCli) CmdInspect(args ...string) error {
848 848
 	cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container or image")
849 849
 	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.")
850
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
850
+	cmd.Require(flag.Min, 1)
851 851
 
852
-	if err := cmd.Parse(args); err != nil {
852
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
853 853
 		return nil
854 854
 	}
855
-	if *help {
856
-		cmd.Usage()
857
-		return nil
858
-	}
859
-	if cmd.BadArgs(flag.Min, 1) {
860
-		os.Exit(1)
861
-	}
862 855
 
863 856
 	var tmpl *template.Template
864 857
 	if *tmplStr != "" {
... ...
@@ -931,18 +881,12 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
931 931
 
932 932
 func (cli *DockerCli) CmdTop(args ...string) error {
933 933
 	cmd := cli.Subcmd("top", "CONTAINER [ps OPTIONS]", "Display the running processes of a container")
934
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
934
+	cmd.Require(flag.Min, 1)
935 935
 
936
-	if err := cmd.Parse(args); err != nil {
937
-		return nil
938
-	}
939
-	if *help {
940
-		cmd.Usage()
936
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
941 937
 		return nil
942 938
 	}
943
-	if cmd.BadArgs(flag.Min, 1) {
944
-		os.Exit(1)
945
-	}
939
+
946 940
 	val := url.Values{}
947 941
 	if cmd.NArg() > 1 {
948 942
 		val.Set("ps_args", strings.Join(cmd.Args()[1:], " "))
... ...
@@ -971,17 +915,10 @@ func (cli *DockerCli) CmdTop(args ...string) error {
971 971
 
972 972
 func (cli *DockerCli) CmdPort(args ...string) error {
973 973
 	cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT")
974
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
975
-	if err := cmd.Parse(args); err != nil {
974
+	cmd.Require(flag.Min, 1)
975
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
976 976
 		return nil
977 977
 	}
978
-	if *help {
979
-		cmd.Usage()
980
-		return nil
981
-	}
982
-	if cmd.BadArgs(flag.Min, 1) {
983
-		os.Exit(1)
984
-	}
985 978
 
986 979
 	stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false)
987 980
 	if err != nil {
... ...
@@ -1034,18 +971,11 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
1034 1034
 		force   = cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image")
1035 1035
 		noprune = cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents")
1036 1036
 	)
1037
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1037
+	cmd.Require(flag.Min, 1)
1038 1038
 
1039
-	if err := cmd.Parse(args); err != nil {
1039
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1040 1040
 		return nil
1041 1041
 	}
1042
-	if *help {
1043
-		cmd.Usage()
1044
-		return nil
1045
-	}
1046
-	if cmd.BadArgs(flag.Min, 1) {
1047
-		os.Exit(1)
1048
-	}
1049 1042
 
1050 1043
 	v := url.Values{}
1051 1044
 	if *force {
... ...
@@ -1084,18 +1014,11 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
1084 1084
 	cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image")
1085 1085
 	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
1086 1086
 	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
1087
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1087
+	cmd.Require(flag.Exact, 1)
1088 1088
 
1089
-	if err := cmd.Parse(args); err != nil {
1089
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1090 1090
 		return nil
1091 1091
 	}
1092
-	if *help {
1093
-		cmd.Usage()
1094
-		return nil
1095
-	}
1096
-	if cmd.BadArgs(flag.Exact, 1) {
1097
-		os.Exit(1)
1098
-	}
1099 1092
 
1100 1093
 	body, _, err := readBody(cli.call("GET", "/images/"+cmd.Arg(0)+"/history", nil, false))
1101 1094
 	if err != nil {
... ...
@@ -1146,18 +1069,11 @@ func (cli *DockerCli) CmdRm(args ...string) error {
1146 1146
 	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container")
1147 1147
 	link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container")
1148 1148
 	force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
1149
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1149
+	cmd.Require(flag.Min, 1)
1150 1150
 
1151
-	if err := cmd.Parse(args); err != nil {
1151
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1152 1152
 		return nil
1153 1153
 	}
1154
-	if *help {
1155
-		cmd.Usage()
1156
-		return nil
1157
-	}
1158
-	if cmd.BadArgs(flag.Min, 1) {
1159
-		os.Exit(1)
1160
-	}
1161 1154
 
1162 1155
 	val := url.Values{}
1163 1156
 	if *v {
... ...
@@ -1188,18 +1104,11 @@ func (cli *DockerCli) CmdRm(args ...string) error {
1188 1188
 func (cli *DockerCli) CmdKill(args ...string) error {
1189 1189
 	cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal")
1190 1190
 	signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container")
1191
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1191
+	cmd.Require(flag.Min, 1)
1192 1192
 
1193
-	if err := cmd.Parse(args); err != nil {
1193
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1194 1194
 		return nil
1195 1195
 	}
1196
-	if *help {
1197
-		cmd.Usage()
1198
-		return nil
1199
-	}
1200
-	if cmd.BadArgs(flag.Min, 1) {
1201
-		os.Exit(1)
1202
-	}
1203 1196
 
1204 1197
 	var encounteredError error
1205 1198
 	for _, name := range cmd.Args() {
... ...
@@ -1215,18 +1124,12 @@ func (cli *DockerCli) CmdKill(args ...string) error {
1215 1215
 
1216 1216
 func (cli *DockerCli) CmdImport(args ...string) error {
1217 1217
 	cmd := cli.Subcmd("import", "URL|- [REPOSITORY[:TAG]]", "Create an empty filesystem image and import the contents of the tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then optionally tag it.")
1218
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1218
+	cmd.Require(flag.Min, 1)
1219 1219
 
1220
-	if err := cmd.Parse(args); err != nil {
1220
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1221 1221
 		return nil
1222 1222
 	}
1223
-	if *help {
1224
-		cmd.Usage()
1225
-		return nil
1226
-	}
1227
-	if cmd.BadArgs(flag.Min, 1) {
1228
-		os.Exit(1)
1229
-	}
1223
+
1230 1224
 	var (
1231 1225
 		v          = url.Values{}
1232 1226
 		src        = cmd.Arg(0)
... ...
@@ -1260,18 +1163,12 @@ func (cli *DockerCli) CmdImport(args ...string) error {
1260 1260
 
1261 1261
 func (cli *DockerCli) CmdPush(args ...string) error {
1262 1262
 	cmd := cli.Subcmd("push", "NAME[:TAG]", "Push an image or a repository to the registry")
1263
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1263
+	cmd.Require(flag.Exact, 1)
1264 1264
 
1265
-	if err := cmd.Parse(args); err != nil {
1265
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1266 1266
 		return nil
1267 1267
 	}
1268
-	if *help {
1269
-		cmd.Usage()
1270
-		return nil
1271
-	}
1272
-	if cmd.BadArgs(flag.Exact, 1) {
1273
-		os.Exit(1)
1274
-	}
1268
+
1275 1269
 	name := cmd.Arg(0)
1276 1270
 
1277 1271
 	cli.LoadConfigFile()
... ...
@@ -1330,19 +1227,12 @@ func (cli *DockerCli) CmdPush(args ...string) error {
1330 1330
 func (cli *DockerCli) CmdPull(args ...string) error {
1331 1331
 	cmd := cli.Subcmd("pull", "NAME[:TAG]", "Pull an image or a repository from the registry")
1332 1332
 	allTags := cmd.Bool([]string{"a", "-all-tags"}, false, "Download all tagged images in the repository")
1333
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1333
+	cmd.Require(flag.Exact, 1)
1334 1334
 
1335
-	if err := cmd.Parse(args); err != nil {
1336
-		return nil
1337
-	}
1338
-	if *help {
1339
-		cmd.Usage()
1335
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1340 1336
 		return nil
1341 1337
 	}
1342 1338
 
1343
-	if cmd.BadArgs(flag.Exact, 1) {
1344
-		os.Exit(1)
1345
-	}
1346 1339
 	var (
1347 1340
 		v         = url.Values{}
1348 1341
 		remote    = cmd.Arg(0)
... ...
@@ -1406,21 +1296,14 @@ func (cli *DockerCli) CmdImages(args ...string) error {
1406 1406
 	// FIXME: --viz and --tree are deprecated. Remove them in a future version.
1407 1407
 	flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format")
1408 1408
 	flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format")
1409
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1410 1409
 
1411 1410
 	flFilter := opts.NewListOpts(nil)
1412 1411
 	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")
1412
+	cmd.Require(flag.Max, 1)
1413 1413
 
1414
-	if err := cmd.Parse(args); err != nil {
1415
-		return nil
1416
-	}
1417
-	if *help {
1418
-		cmd.Usage()
1414
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1419 1415
 		return nil
1420 1416
 	}
1421
-	if cmd.BadArgs(flag.Max, 1) {
1422
-		os.Exit(1)
1423
-	}
1424 1417
 
1425 1418
 	// Consolidate all filter flags, and sanity check them early.
1426 1419
 	// They'll get process in the daemon/server.
... ...
@@ -1650,7 +1533,6 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1650 1650
 		quiet    = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
1651 1651
 		size     = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
1652 1652
 		all      = cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.")
1653
-		help     = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1654 1653
 		noTrunc  = cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
1655 1654
 		nLatest  = cmd.Bool([]string{"l", "-latest"}, false, "Show only the latest created container, include non-running ones.")
1656 1655
 		since    = cmd.String([]string{"#sinceId", "#-since-id", "-since"}, "", "Show only containers created since Id or Name, include non-running ones.")
... ...
@@ -1658,14 +1540,11 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1658 1658
 		last     = cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.")
1659 1659
 		flFilter = opts.NewListOpts(nil)
1660 1660
 	)
1661
+	cmd.Require(flag.Exact, 0)
1661 1662
 
1662 1663
 	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited=<int> - containers with exit code of <int>\nstatus=(restarting|running|paused|exited)")
1663 1664
 
1664
-	if err := cmd.Parse(args); err != nil {
1665
-		return nil
1666
-	}
1667
-	if *help {
1668
-		cmd.Usage()
1665
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1669 1666
 		return nil
1670 1667
 	}
1671 1668
 	if *last == -1 && *nLatest {
... ...
@@ -1808,22 +1687,11 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
1808 1808
 	flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
1809 1809
 	// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
1810 1810
 	flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
1811
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1812
-	if err := cmd.Parse(args); err != nil {
1811
+	cmd.Require(flag.Max, 2)
1812
+	cmd.Require(flag.Min, 1)
1813
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1813 1814
 		return nil
1814 1815
 	}
1815
-	if *help {
1816
-		cmd.Usage()
1817
-		return nil
1818
-	}
1819
-
1820
-	if cmd.BadArgs(flag.Max, 2) {
1821
-		os.Exit(1)
1822
-	}
1823
-
1824
-	if cmd.BadArgs(flag.Min, 1) {
1825
-		os.Exit(1)
1826
-	}
1827 1816
 
1828 1817
 	var (
1829 1818
 		name            = cmd.Arg(0)
... ...
@@ -1876,18 +1744,11 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
1876 1876
 	until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
1877 1877
 	flFilter := opts.NewListOpts(nil)
1878 1878
 	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'event=stop')")
1879
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1879
+	cmd.Require(flag.Exact, 0)
1880 1880
 
1881
-	if err := cmd.Parse(args); err != nil {
1882
-		return nil
1883
-	}
1884
-	if *help {
1885
-		cmd.Usage()
1881
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1886 1882
 		return nil
1887 1883
 	}
1888
-	if cmd.BadArgs(flag.Exact, 0) {
1889
-		os.Exit(1)
1890
-	}
1891 1884
 
1892 1885
 	var (
1893 1886
 		v               = url.Values{}
... ...
@@ -1936,18 +1797,11 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
1936 1936
 
1937 1937
 func (cli *DockerCli) CmdExport(args ...string) error {
1938 1938
 	cmd := cli.Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive to STDOUT")
1939
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1939
+	cmd.Require(flag.Exact, 1)
1940 1940
 
1941
-	if err := cmd.Parse(args); err != nil {
1942
-		return nil
1943
-	}
1944
-	if *help {
1945
-		cmd.Usage()
1941
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1946 1942
 		return nil
1947 1943
 	}
1948
-	if cmd.BadArgs(flag.Exact, 1) {
1949
-		os.Exit(1)
1950
-	}
1951 1944
 
1952 1945
 	if err := cli.stream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, cli.out, nil); err != nil {
1953 1946
 		return err
... ...
@@ -1957,18 +1811,11 @@ func (cli *DockerCli) CmdExport(args ...string) error {
1957 1957
 
1958 1958
 func (cli *DockerCli) CmdDiff(args ...string) error {
1959 1959
 	cmd := cli.Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
1960
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
1960
+	cmd.Require(flag.Exact, 1)
1961 1961
 
1962
-	if err := cmd.Parse(args); err != nil {
1962
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
1963 1963
 		return nil
1964 1964
 	}
1965
-	if *help {
1966
-		cmd.Usage()
1967
-		return nil
1968
-	}
1969
-	if cmd.BadArgs(flag.Exact, 1) {
1970
-		os.Exit(1)
1971
-	}
1972 1965
 
1973 1966
 	body, _, err := readBody(cli.call("GET", "/containers/"+cmd.Arg(0)+"/changes", nil, false))
1974 1967
 
... ...
@@ -2001,20 +1848,13 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
2001 2001
 		follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
2002 2002
 		times  = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
2003 2003
 		tail   = cmd.String([]string{"-tail"}, "all", "Output the specified number of lines at the end of logs (defaults to all logs)")
2004
-		help   = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2005 2004
 	)
2005
+	cmd.Require(flag.Exact, 1)
2006 2006
 
2007
-	if err := cmd.Parse(args); err != nil {
2007
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2008 2008
 		return nil
2009 2009
 	}
2010 2010
 
2011
-	if *help {
2012
-		cmd.Usage()
2013
-		return nil
2014
-	}
2015
-	if cmd.BadArgs(flag.Exact, 1) {
2016
-		os.Exit(1)
2017
-	}
2018 2011
 	name := cmd.Arg(0)
2019 2012
 
2020 2013
 	stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false)
... ...
@@ -2048,19 +1888,12 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
2048 2048
 		cmd     = cli.Subcmd("attach", "CONTAINER", "Attach to a running container")
2049 2049
 		noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN")
2050 2050
 		proxy   = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process (non-TTY mode only). SIGCHLD, SIGKILL, and SIGSTOP are not proxied.")
2051
-		help    = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2052 2051
 	)
2052
+	cmd.Require(flag.Exact, 1)
2053 2053
 
2054
-	if err := cmd.Parse(args); err != nil {
2055
-		return nil
2056
-	}
2057
-	if *help {
2058
-		cmd.Usage()
2054
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2059 2055
 		return nil
2060 2056
 	}
2061
-	if cmd.BadArgs(flag.Exact, 1) {
2062
-		os.Exit(1)
2063
-	}
2064 2057
 	name := cmd.Arg(0)
2065 2058
 
2066 2059
 	stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, false)
... ...
@@ -2130,18 +1963,11 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
2130 2130
 	trusted := cmd.Bool([]string{"#t", "#trusted", "#-trusted"}, false, "Only show trusted builds")
2131 2131
 	automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds")
2132 2132
 	stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least x stars")
2133
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2133
+	cmd.Require(flag.Exact, 1)
2134 2134
 
2135
-	if err := cmd.Parse(args); err != nil {
2136
-		return nil
2137
-	}
2138
-	if *help {
2139
-		cmd.Usage()
2135
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2140 2136
 		return nil
2141 2137
 	}
2142
-	if cmd.BadArgs(flag.Exact, 1) {
2143
-		os.Exit(1)
2144
-	}
2145 2138
 
2146 2139
 	v := url.Values{}
2147 2140
 	v.Set("term", cmd.Arg(0))
... ...
@@ -2187,18 +2013,11 @@ type ports []int
2187 2187
 func (cli *DockerCli) CmdTag(args ...string) error {
2188 2188
 	cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository")
2189 2189
 	force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
2190
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2190
+	cmd.Require(flag.Exact, 2)
2191 2191
 
2192
-	if err := cmd.Parse(args); err != nil {
2193
-		return nil
2194
-	}
2195
-	if *help {
2196
-		cmd.Usage()
2192
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2197 2193
 		return nil
2198 2194
 	}
2199
-	if cmd.BadArgs(flag.Exact, 2) {
2200
-		os.Exit(1)
2201
-	}
2202 2195
 
2203 2196
 	var (
2204 2197
 		repository, tag = parsers.ParseRepositoryTag(cmd.Arg(1))
... ...
@@ -2588,18 +2407,11 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2588 2588
 
2589 2589
 func (cli *DockerCli) CmdCp(args ...string) error {
2590 2590
 	cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH")
2591
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2591
+	cmd.Require(flag.Exact, 2)
2592 2592
 
2593
-	if err := cmd.Parse(args); err != nil {
2594
-		return nil
2595
-	}
2596
-	if *help {
2597
-		cmd.Usage()
2593
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2598 2594
 		return nil
2599 2595
 	}
2600
-	if cmd.BadArgs(flag.Exact, 2) {
2601
-		os.Exit(1)
2602
-	}
2603 2596
 
2604 2597
 	var copyData engine.Env
2605 2598
 	info := strings.Split(cmd.Arg(0), ":")
... ...
@@ -2632,21 +2444,13 @@ func (cli *DockerCli) CmdCp(args ...string) error {
2632 2632
 
2633 2633
 func (cli *DockerCli) CmdSave(args ...string) error {
2634 2634
 	cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)")
2635
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2636 2635
 	outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
2636
+	cmd.Require(flag.Min, 1)
2637 2637
 
2638
-	if err := cmd.Parse(args); err != nil {
2638
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2639 2639
 		return err
2640 2640
 	}
2641 2641
 
2642
-	if *help {
2643
-		cmd.Usage()
2644
-		return nil
2645
-	}
2646
-	if cmd.BadArgs(flag.Min, 1) {
2647
-		os.Exit(1)
2648
-	}
2649
-
2650 2642
 	var (
2651 2643
 		output io.Writer = cli.out
2652 2644
 		err    error
... ...
@@ -2680,18 +2484,11 @@ func (cli *DockerCli) CmdSave(args ...string) error {
2680 2680
 func (cli *DockerCli) CmdLoad(args ...string) error {
2681 2681
 	cmd := cli.Subcmd("load", "", "Load an image from a tar archive on STDIN")
2682 2682
 	infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN")
2683
-	help := cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
2683
+	cmd.Require(flag.Exact, 0)
2684 2684
 
2685
-	if err := cmd.Parse(args); err != nil {
2685
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
2686 2686
 		return err
2687 2687
 	}
2688
-	if *help {
2689
-		cmd.Usage()
2690
-		return nil
2691
-	}
2692
-	if cmd.BadArgs(flag.Exact, 0) {
2693
-		os.Exit(1)
2694
-	}
2695 2688
 
2696 2689
 	var (
2697 2690
 		input io.Reader = cli.in
... ...
@@ -284,13 +284,14 @@ type FlagSet struct {
284 284
 	// a custom error handler.
285 285
 	Usage func()
286 286
 
287
-	name          string
288
-	parsed        bool
289
-	actual        map[string]*Flag
290
-	formal        map[string]*Flag
291
-	args          []string // arguments after flags
292
-	errorHandling ErrorHandling
293
-	output        io.Writer // nil means stderr; use out() accessor
287
+	name             string
288
+	parsed           bool
289
+	actual           map[string]*Flag
290
+	formal           map[string]*Flag
291
+	args             []string // arguments after flags
292
+	errorHandling    ErrorHandling
293
+	output           io.Writer // nil means stderr; use Out() accessor
294
+	nArgRequirements []nArgRequirement
294 295
 }
295 296
 
296 297
 // A Flag represents the state of a flag.
... ...
@@ -348,7 +349,13 @@ func sortFlags(flags map[string]*Flag) []*Flag {
348 348
 	return result
349 349
 }
350 350
 
351
-func (f *FlagSet) out() io.Writer {
351
+// Name returns the name of the FlagSet.
352
+func (f *FlagSet) Name() string {
353
+	return f.name
354
+}
355
+
356
+// Out returns the destination for usage and error messages.
357
+func (f *FlagSet) Out() io.Writer {
352 358
 	if f.output == nil {
353 359
 		return os.Stderr
354 360
 	}
... ...
@@ -410,45 +417,60 @@ func IsSet(name string) bool {
410 410
 	return CommandLine.IsSet(name)
411 411
 }
412 412
 
413
+type nArgRequirementType int
414
+
413 415
 // Indicator used to pass to BadArgs function
414 416
 const (
415
-	Exact = 1
416
-	Max   = 2
417
-	Min   = 3
417
+	Exact nArgRequirementType = iota
418
+	Max
419
+	Min
418 420
 )
419 421
 
420
-// Bad Args takes two arguments.
421
-// The first one indicates whether the number of arguments should, be
422
-// A Minimal number of arguments, a maximum number of arguments or
423
-// The exact number of arguments required
424
-// If the actuall number of arguments is not valid and error message
425
-// prints and true is returned, otherwise false is returned
426
-func (f *FlagSet) BadArgs(arg_type, nargs int) bool {
427
-	if arg_type == Max && f.NArg() > nargs {
428
-		if nargs == 1 {
429
-			fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
422
+type nArgRequirement struct {
423
+	Type nArgRequirementType
424
+	N    int
425
+}
426
+
427
+// Require adds a requirement about the number of arguments for the FlagSet.
428
+// The first parameter can be Exact, Max, or Min to respectively specify the exact,
429
+// the maximum, or the minimal number of arguments required.
430
+// The actual check is done in FlagSet.CheckArgs().
431
+func (f *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) {
432
+	f.nArgRequirements = append(f.nArgRequirements, nArgRequirement{nArgRequirementType, nArg})
433
+}
434
+
435
+// CheckArgs uses the requirements set by FlagSet.Require() to validate
436
+// the number of arguments. If the requirements are not met,
437
+// an error message string is returned.
438
+func (f *FlagSet) CheckArgs() (message string) {
439
+	for _, req := range f.nArgRequirements {
440
+		var arguments string
441
+		if req.N == 1 {
442
+			arguments = "1 argument"
430 443
 		} else {
431
-			fmt.Fprintf(f.out(), "docker: '%s' requires a maximum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
444
+			arguments = fmt.Sprintf("%d arguments", req.N)
432 445
 		}
433
-		return true
434
-	}
435
-	if arg_type == Exact && f.NArg() != nargs {
436
-		if nargs == 1 {
437
-			fmt.Fprintf(f.out(), "docker: '%s' requires 1 argument. See 'docker %s --help'.\n", f.name, f.name)
438
-		} else {
439
-			fmt.Fprintf(f.out(), "docker: '%s' requires %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
446
+
447
+		str := func(kind string) string {
448
+			return fmt.Sprintf("%q requires %s%s", f.name, kind, arguments)
440 449
 		}
441
-		return true
442
-	}
443
-	if arg_type == Min && f.NArg() < nargs {
444
-		if nargs == 1 {
445
-			fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of 1 argument. See 'docker %s --help'.\n", f.name, f.name)
446
-		} else {
447
-			fmt.Fprintf(f.out(), "docker: '%s' requires a minimum of %d arguments. See 'docker %s --help'.\n", f.name, nargs, f.name)
450
+
451
+		switch req.Type {
452
+		case Exact:
453
+			if f.NArg() != req.N {
454
+				return str("")
455
+			}
456
+		case Max:
457
+			if f.NArg() > req.N {
458
+				return str("a maximum of ")
459
+			}
460
+		case Min:
461
+			if f.NArg() < req.N {
462
+				return str("a minimum of ")
463
+			}
448 464
 		}
449
-		return true
450 465
 	}
451
-	return false
466
+	return ""
452 467
 }
453 468
 
454 469
 // Set sets the value of the named flag.
... ...
@@ -476,7 +498,7 @@ func Set(name, value string) error {
476 476
 // PrintDefaults prints, to standard error unless configured
477 477
 // otherwise, the default values of all defined flags in the set.
478 478
 func (f *FlagSet) PrintDefaults() {
479
-	writer := tabwriter.NewWriter(f.out(), 20, 1, 3, ' ', 0)
479
+	writer := tabwriter.NewWriter(f.Out(), 20, 1, 3, ' ', 0)
480 480
 	f.VisitAll(func(flag *Flag) {
481 481
 		format := "  -%s=%s"
482 482
 		if _, ok := flag.Value.(*stringValue); ok {
... ...
@@ -510,9 +532,9 @@ func PrintDefaults() {
510 510
 // defaultUsage is the default function to print a usage message.
511 511
 func defaultUsage(f *FlagSet) {
512 512
 	if f.name == "" {
513
-		fmt.Fprintf(f.out(), "Usage:\n")
513
+		fmt.Fprintf(f.Out(), "Usage:\n")
514 514
 	} else {
515
-		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
515
+		fmt.Fprintf(f.Out(), "Usage of %s:\n", f.name)
516 516
 	}
517 517
 	f.PrintDefaults()
518 518
 }
... ...
@@ -805,7 +827,7 @@ func (f *FlagSet) Var(value Value, names []string, usage string) {
805 805
 			} else {
806 806
 				msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
807 807
 			}
808
-			fmt.Fprintln(f.out(), msg)
808
+			fmt.Fprintln(f.Out(), msg)
809 809
 			panic(msg) // Happens only if flags are declared with identical names
810 810
 		}
811 811
 		if f.formal == nil {
... ...
@@ -829,8 +851,8 @@ func Var(value Value, names []string, usage string) {
829 829
 // returns the error.
830 830
 func (f *FlagSet) failf(format string, a ...interface{}) error {
831 831
 	err := fmt.Errorf(format, a...)
832
-	fmt.Fprintln(f.out(), err)
833
-	fmt.Fprintf(f.out(), "See 'docker %s --help'.\n", f.name)
832
+	fmt.Fprintln(f.Out(), err)
833
+	fmt.Fprintf(f.Out(), "See 'docker %s --help'.\n", f.name)
834 834
 	return err
835 835
 }
836 836
 
... ...
@@ -956,9 +978,9 @@ func (f *FlagSet) parseOne() (bool, string, error) {
956 956
 				}
957 957
 			}
958 958
 			if replacement != "" {
959
-				fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
959
+				fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
960 960
 			} else {
961
-				fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
961
+				fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
962 962
 			}
963 963
 		}
964 964
 	}
... ...
@@ -5,7 +5,7 @@ import (
5 5
 
6 6
 	"github.com/docker/docker/engine"
7 7
 	flag "github.com/docker/docker/pkg/mflag"
8
-	"os"
8
+	"github.com/docker/docker/utils"
9 9
 )
10 10
 
11 11
 type ExecConfig struct {
... ...
@@ -46,20 +46,13 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
46 46
 		flStdin   = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
47 47
 		flTty     = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
48 48
 		flDetach  = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: run command in the background")
49
-		help      = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
50 49
 		execCmd   []string
51 50
 		container string
52 51
 	)
53
-	if err := cmd.Parse(args); err != nil {
52
+	cmd.Require(flag.Min, 2)
53
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
54 54
 		return nil, err
55 55
 	}
56
-	if *help {
57
-		cmd.Usage()
58
-		return nil, nil
59
-	}
60
-	if cmd.BadArgs(flag.Min, 2) {
61
-		os.Exit(1)
62
-	}
63 56
 	container = cmd.Arg(0)
64 57
 	parsedArgs := cmd.Args()
65 58
 	execCmd = parsedArgs[1:]
... ...
@@ -2,7 +2,6 @@ package runconfig
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"os"
6 5
 	"path"
7 6
 	"strconv"
8 7
 	"strings"
... ...
@@ -62,7 +61,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
62 62
 		flMacAddress      = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
63 63
 		flIpcMode         = cmd.String([]string{"-ipc"}, "", "Default is to create a private IPC namespace (POSIX SysV IPC) for the container\n'container:<name|id>': reuses another container shared memory, semaphores and message queues\n'host': use the host shared memory,semaphores and message queues inside the container.  Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.")
64 64
 		flRestartPolicy   = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)")
65
-		help              = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
66 65
 	)
67 66
 
68 67
 	cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR.")
... ...
@@ -85,16 +83,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
85 85
 	cmd.Var(&flCapDrop, []string{"-cap-drop"}, "Drop Linux capabilities")
86 86
 	cmd.Var(&flSecurityOpt, []string{"-security-opt"}, "Security Options")
87 87
 
88
-	if err := cmd.Parse(args); err != nil {
88
+	cmd.Require(flag.Min, 1)
89
+
90
+	if err := utils.ParseFlags(cmd, args, true); err != nil {
89 91
 		return nil, nil, cmd, err
90 92
 	}
91
-	if *help {
92
-		cmd.Usage()
93
-		return nil, nil, cmd, nil
94
-	}
95
-	if cmd.BadArgs(flag.Min, 1) {
96
-		os.Exit(1)
97
-	}
98 93
 
99 94
 	// Validate input params
100 95
 	if *flWorkingDir != "" && !path.IsAbs(*flWorkingDir) {
101 96
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+package utils
1
+
2
+import (
3
+	"fmt"
4
+	"os"
5
+
6
+	flag "github.com/docker/docker/pkg/mflag"
7
+)
8
+
9
+// ParseFlags is a utility function that adds a help flag if withHelp is true,
10
+// calls cmd.Parse(args) and prints a relevant error message if there are incorrect number of arguments.
11
+// TODO: move this to a better package than utils
12
+func ParseFlags(cmd *flag.FlagSet, args []string, withHelp bool) error {
13
+	var help *bool
14
+	if withHelp {
15
+		help = cmd.Bool([]string{"#help", "-help"}, false, "Print usage")
16
+	}
17
+	if err := cmd.Parse(args); err != nil {
18
+		return err
19
+	}
20
+	if help != nil && *help {
21
+		cmd.Usage()
22
+		// just in case Usage does not exit
23
+		os.Exit(0)
24
+	}
25
+	if str := cmd.CheckArgs(); str != "" {
26
+		if withHelp {
27
+			str += ". See 'docker " + cmd.Name() + " --help'"
28
+		}
29
+		fmt.Fprintf(cmd.Out(), "docker: %s.\n", str)
30
+		os.Exit(1)
31
+	}
32
+	return nil
33
+}