Browse code

add the [OPTIONS] string automatically if there are flags defined

Signed-off-by: SvenDowideit <SvenDowideit@home.org.au>

Docker-DCO-1.1-Signed-off-by: SvenDowideit <SvenDowideit@home.org.au> (github: SvenDowideit)

SvenDowideit authored on 2014/08/25 10:53:31
Showing 5 changed files
... ...
@@ -63,7 +63,11 @@ func (cli *DockerCli) Cmd(args ...string) error {
63 63
 func (cli *DockerCli) Subcmd(name, signature, description string) *flag.FlagSet {
64 64
 	flags := flag.NewFlagSet(name, flag.ContinueOnError)
65 65
 	flags.Usage = func() {
66
-		fmt.Fprintf(cli.err, "\nUsage: docker %s %s\n\n%s\n\n", name, signature, description)
66
+		options := ""
67
+		if flags.FlagCountUndeprecated() > 0 {
68
+			options = "[OPTIONS] "
69
+		}
70
+		fmt.Fprintf(cli.err, "\nUsage: docker %s %s%s\n\n%s\n\n", name, options, signature, description)
67 71
 		flags.PrintDefaults()
68 72
 		os.Exit(2)
69 73
 	}
... ...
@@ -98,7 +98,7 @@ func (cli *DockerCli) CmdHelp(args ...string) error {
98 98
 }
99 99
 
100 100
 func (cli *DockerCli) CmdBuild(args ...string) error {
101
-	cmd := cli.Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new image from the source code at PATH")
101
+	cmd := cli.Subcmd("build", "PATH | URL | -", "Build a new image from the source code at PATH")
102 102
 	tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
103 103
 	suppressOutput := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the verbose output generated by the containers")
104 104
 	noCache := cmd.Bool([]string{"#no-cache", "-no-cache"}, false, "Do not use cache when building the image")
... ...
@@ -255,7 +255,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
255 255
 
256 256
 // 'docker login': login / register a user to registry service.
257 257
 func (cli *DockerCli) CmdLogin(args ...string) error {
258
-	cmd := cli.Subcmd("login", "[OPTIONS] [SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
258
+	cmd := cli.Subcmd("login", "[SERVER]", "Register or log in to a Docker registry server, if no server is specified \""+registry.IndexServerAddress()+"\" is the default.")
259 259
 
260 260
 	var username, password, email string
261 261
 
... ...
@@ -529,7 +529,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
529 529
 }
530 530
 
531 531
 func (cli *DockerCli) CmdStop(args ...string) error {
532
-	cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period")
532
+	cmd := cli.Subcmd("stop", "CONTAINER [CONTAINER...]", "Stop a running container by sending SIGTERM and then SIGKILL after a grace period")
533 533
 	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it. Default is 10 seconds.")
534 534
 	if err := cmd.Parse(args); err != nil {
535 535
 		return nil
... ...
@@ -556,7 +556,7 @@ func (cli *DockerCli) CmdStop(args ...string) error {
556 556
 }
557 557
 
558 558
 func (cli *DockerCli) CmdRestart(args ...string) error {
559
-	cmd := cli.Subcmd("restart", "[OPTIONS] CONTAINER [CONTAINER...]", "Restart a running container")
559
+	cmd := cli.Subcmd("restart", "CONTAINER [CONTAINER...]", "Restart a running container")
560 560
 	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.")
561 561
 	if err := cmd.Parse(args); err != nil {
562 562
 		return nil
... ...
@@ -954,7 +954,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
954 954
 }
955 955
 
956 956
 func (cli *DockerCli) CmdHistory(args ...string) error {
957
-	cmd := cli.Subcmd("history", "[OPTIONS] IMAGE", "Show the history of an image")
957
+	cmd := cli.Subcmd("history", "IMAGE", "Show the history of an image")
958 958
 	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
959 959
 	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
960 960
 
... ...
@@ -1011,7 +1011,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
1011 1011
 }
1012 1012
 
1013 1013
 func (cli *DockerCli) CmdRm(args ...string) error {
1014
-	cmd := cli.Subcmd("rm", "[OPTIONS] CONTAINER [CONTAINER...]", "Remove one or more containers")
1014
+	cmd := cli.Subcmd("rm", "CONTAINER [CONTAINER...]", "Remove one or more containers")
1015 1015
 	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container")
1016 1016
 	link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container")
1017 1017
 	force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
... ...
@@ -1051,7 +1051,7 @@ func (cli *DockerCli) CmdRm(args ...string) error {
1051 1051
 
1052 1052
 // 'docker kill NAME' kills a running container
1053 1053
 func (cli *DockerCli) CmdKill(args ...string) error {
1054
-	cmd := cli.Subcmd("kill", "[OPTIONS] CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal")
1054
+	cmd := cli.Subcmd("kill", "CONTAINER [CONTAINER...]", "Kill a running container using SIGKILL or a specified signal")
1055 1055
 	signal := cmd.String([]string{"s", "-signal"}, "KILL", "Signal to send to the container")
1056 1056
 
1057 1057
 	if err := cmd.Parse(args); err != nil {
... ...
@@ -1245,7 +1245,7 @@ func (cli *DockerCli) CmdPull(args ...string) error {
1245 1245
 }
1246 1246
 
1247 1247
 func (cli *DockerCli) CmdImages(args ...string) error {
1248
-	cmd := cli.Subcmd("images", "[OPTIONS] [NAME]", "List images")
1248
+	cmd := cli.Subcmd("images", "[NAME]", "List images")
1249 1249
 	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
1250 1250
 	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (by default filter out the intermediate image layers)")
1251 1251
 	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
... ...
@@ -1476,7 +1476,7 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri
1476 1476
 }
1477 1477
 
1478 1478
 func (cli *DockerCli) CmdPs(args ...string) error {
1479
-	cmd := cli.Subcmd("ps", "[OPTIONS]", "List containers")
1479
+	cmd := cli.Subcmd("ps", "", "List containers")
1480 1480
 	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
1481 1481
 	size := cmd.Bool([]string{"s", "-size"}, false, "Display sizes")
1482 1482
 	all := cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.")
... ...
@@ -1598,7 +1598,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1598 1598
 }
1599 1599
 
1600 1600
 func (cli *DockerCli) CmdCommit(args ...string) error {
1601
-	cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes")
1601
+	cmd := cli.Subcmd("commit", "CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes")
1602 1602
 	flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
1603 1603
 	flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
1604 1604
 	flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
... ...
@@ -1659,7 +1659,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
1659 1659
 }
1660 1660
 
1661 1661
 func (cli *DockerCli) CmdEvents(args ...string) error {
1662
-	cmd := cli.Subcmd("events", "[OPTIONS]", "Get real time events from the server")
1662
+	cmd := cli.Subcmd("events", "", "Get real time events from the server")
1663 1663
 	since := cmd.String([]string{"#since", "-since"}, "", "Show all events created since timestamp")
1664 1664
 	until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
1665 1665
 	if err := cmd.Parse(args); err != nil {
... ...
@@ -1795,7 +1795,7 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
1795 1795
 
1796 1796
 func (cli *DockerCli) CmdAttach(args ...string) error {
1797 1797
 	var (
1798
-		cmd     = cli.Subcmd("attach", "[OPTIONS] CONTAINER", "Attach to a running container")
1798
+		cmd     = cli.Subcmd("attach", "CONTAINER", "Attach to a running container")
1799 1799
 		noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN")
1800 1800
 		proxy   = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process (even in non-TTY mode). SIGCHLD, SIGKILL, and SIGSTOP are not proxied.")
1801 1801
 	)
... ...
@@ -1923,7 +1923,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
1923 1923
 type ports []int
1924 1924
 
1925 1925
 func (cli *DockerCli) CmdTag(args ...string) error {
1926
-	cmd := cli.Subcmd("tag", "[OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository")
1926
+	cmd := cli.Subcmd("tag", "IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]", "Tag an image into a repository")
1927 1927
 	force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
1928 1928
 	if err := cmd.Parse(args); err != nil {
1929 1929
 		return nil
... ...
@@ -1992,7 +1992,7 @@ func (cli *DockerCli) pullImage(image string) error {
1992 1992
 
1993 1993
 func (cli *DockerCli) CmdRun(args ...string) error {
1994 1994
 	// FIXME: just use runconfig.Parse already
1995
-	config, hostConfig, cmd, err := runconfig.ParseSubcommand(cli.Subcmd("run", "[OPTIONS] IMAGE [COMMAND] [ARG...]", "Run a command in a new container"), args, nil)
1995
+	config, hostConfig, cmd, err := runconfig.ParseSubcommand(cli.Subcmd("run", "IMAGE [COMMAND] [ARG...]", "Run a command in a new container"), args, nil)
1996 1996
 	if err != nil {
1997 1997
 		return err
1998 1998
 	}
... ...
@@ -625,7 +625,7 @@ ensure we know how your setup is configured.
625 625
 
626 626
 ## inspect
627 627
 
628
-    Usage: docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]
628
+    Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]
629 629
 
630 630
     Return low-level information on a container or image
631 631
 
... ...
@@ -690,7 +690,7 @@ signal specified with option `--signal`.
690 690
 
691 691
 ## load
692 692
 
693
-    Usage: docker load
693
+    Usage: docker load [OPTIONS]
694 694
 
695 695
     Load an image from a tar archive on STDIN
696 696
 
... ...
@@ -742,7 +742,7 @@ For example:
742 742
 
743 743
 ## logs
744 744
 
745
-    Usage: docker logs CONTAINER
745
+    Usage: docker logs [OPTIONS] CONTAINER
746 746
 
747 747
     Fetch the logs of a container
748 748
 
... ...
@@ -832,7 +832,7 @@ This shows all the containers that have exited with status of '0'
832 832
 
833 833
 ## pull
834 834
 
835
-    Usage: docker pull NAME[:TAG]
835
+    Usage: docker pull [OPTIONS] NAME[:TAG]
836 836
 
837 837
     Pull an image or a repository from the registry
838 838
 
... ...
@@ -922,7 +922,7 @@ delete them. Any running containers will not be deleted.
922 922
 
923 923
 ## rmi
924 924
 
925
-    Usage: docker rmi IMAGE [IMAGE...]
925
+    Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
926 926
 
927 927
     Remove one or more images
928 928
 
... ...
@@ -1249,7 +1249,7 @@ Providing a maximum restart limit is only valid for the ** on-failure ** policy.
1249 1249
 
1250 1250
 ## save
1251 1251
 
1252
-    Usage: docker save IMAGE
1252
+    Usage: docker save [OPTIONS] IMAGE
1253 1253
 
1254 1254
     Save an image to a tar archive (streamed to STDOUT by default)
1255 1255
 
... ...
@@ -1274,7 +1274,7 @@ It is used to create a backup that can then be used with
1274 1274
 
1275 1275
 Search [Docker Hub](https://hub.docker.com) for images
1276 1276
 
1277
-    Usage: docker search TERM
1277
+    Usage: docker search [OPTIONS] TERM
1278 1278
 
1279 1279
     Search the Docker Hub for images
1280 1280
 
... ...
@@ -1288,7 +1288,7 @@ more details on finding shared images from the command line.
1288 1288
 
1289 1289
 ## start
1290 1290
 
1291
-    Usage: docker start CONTAINER [CONTAINER...]
1291
+    Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]
1292 1292
 
1293 1293
     Restart a stopped container
1294 1294
 
... ...
@@ -472,6 +472,23 @@ var Usage = func() {
472 472
 	PrintDefaults()
473 473
 }
474 474
 
475
+// FlagCount returns the number of flags that have been defined.
476
+func (f *FlagSet) FlagCount() int { return len(f.formal) }
477
+
478
+// FlagCountUndeprecated returns the number of undeprecated flags that have been defined.
479
+func (f *FlagSet) FlagCountUndeprecated() int {
480
+	count := 0
481
+	for _, flag := range sortFlags(f.formal) {
482
+		for _, name := range flag.Names {
483
+			if name[0] != '#' {
484
+				count++
485
+				break
486
+			}
487
+		}
488
+	}
489
+	return count
490
+}
491
+
475 492
 // NFlag returns the number of flags that have been set.
476 493
 func (f *FlagSet) NFlag() int { return len(f.actual) }
477 494
 
... ...
@@ -428,3 +428,32 @@ func TestHelp(t *testing.T) {
428 428
 		t.Fatal("help was called; should not have been for defined help flag")
429 429
 	}
430 430
 }
431
+
432
+// Test the flag count functions.
433
+func TestFlagCounts(t *testing.T) {
434
+	fs := NewFlagSet("help test", ContinueOnError)
435
+	var flag bool
436
+	fs.BoolVar(&flag, []string{"flag1"}, false, "regular flag")
437
+	fs.BoolVar(&flag, []string{"#deprecated1"}, false, "regular flag")
438
+	fs.BoolVar(&flag, []string{"f", "flag2"}, false, "regular flag")
439
+	fs.BoolVar(&flag, []string{"#d", "#deprecated2"}, false, "regular flag")
440
+	fs.BoolVar(&flag, []string{"flag3"}, false, "regular flag")
441
+	fs.BoolVar(&flag, []string{"g", "#flag4", "-flag4"}, false, "regular flag")
442
+
443
+	if fs.FlagCount() != 10 {
444
+		t.Fatal("FlagCount wrong. ", fs.FlagCount())
445
+	}
446
+	if fs.FlagCountUndeprecated() != 4 {
447
+		t.Fatal("FlagCountUndeprecated wrong. ", fs.FlagCountUndeprecated())
448
+	}
449
+	if fs.NFlag() != 0 {
450
+		t.Fatal("NFlag wrong. ", fs.NFlag())
451
+	}
452
+	err := fs.Parse([]string{"-fd", "-g", "-flag4"})
453
+	if err != nil {
454
+		t.Fatal("expected no error for defined -help; got ", err)
455
+	}
456
+	if fs.NFlag() != 4 {
457
+		t.Fatal("NFlag wrong. ", fs.NFlag())
458
+	}
459
+}