Browse code

update commands.go

update docker.go

move to pkg

update docs

update name and copyright

change --sinceId to --since-id, update completion and docs

Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor@docker.com> (github: vieux)

Victor Vieux authored on 2013/12/24 04:43:54
Showing 14 changed files
... ...
@@ -7,11 +7,11 @@ import (
7 7
 	"encoding/base64"
8 8
 	"encoding/json"
9 9
 	"errors"
10
-	"flag"
11 10
 	"fmt"
12 11
 	"github.com/dotcloud/docker/archive"
13 12
 	"github.com/dotcloud/docker/auth"
14 13
 	"github.com/dotcloud/docker/engine"
14
+	flag "github.com/dotcloud/docker/pkg/mflag"
15 15
 	"github.com/dotcloud/docker/pkg/term"
16 16
 	"github.com/dotcloud/docker/registry"
17 17
 	"github.com/dotcloud/docker/utils"
... ...
@@ -164,10 +164,10 @@ func MkBuildContext(dockerfile string, files [][2]string) (archive.Archive, erro
164 164
 
165 165
 func (cli *DockerCli) CmdBuild(args ...string) error {
166 166
 	cmd := cli.Subcmd("build", "[OPTIONS] PATH | URL | -", "Build a new container image from the source code at PATH")
167
-	tag := cmd.String("t", "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
168
-	suppressOutput := cmd.Bool("q", false, "Suppress verbose build output")
169
-	noCache := cmd.Bool("no-cache", false, "Do not use cache when building the image")
170
-	rm := cmd.Bool("rm", false, "Remove intermediate containers after a successful build")
167
+	tag := cmd.String([]string{"t", "-tag"}, "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
168
+	suppressOutput := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress verbose build output")
169
+	noCache := cmd.Bool([]string{"#no-cache", "-no-cache"}, false, "Do not use cache when building the image")
170
+	rm := cmd.Bool([]string{"#rm", "-rm"}, false, "Remove intermediate containers after a successful build")
171 171
 	if err := cmd.Parse(args); err != nil {
172 172
 		return nil
173 173
 	}
... ...
@@ -253,9 +253,9 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
253 253
 
254 254
 	var username, password, email string
255 255
 
256
-	cmd.StringVar(&username, "u", "", "username")
257
-	cmd.StringVar(&password, "p", "", "password")
258
-	cmd.StringVar(&email, "e", "", "email")
256
+	cmd.StringVar(&username, []string{"u", "-username"}, "", "username")
257
+	cmd.StringVar(&password, []string{"p", "-password"}, "", "password")
258
+	cmd.StringVar(&email, []string{"e", "-email"}, "", "email")
259 259
 	err := cmd.Parse(args)
260 260
 	if err != nil {
261 261
 		return nil
... ...
@@ -504,7 +504,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
504 504
 
505 505
 func (cli *DockerCli) CmdStop(args ...string) error {
506 506
 	cmd := cli.Subcmd("stop", "[OPTIONS] CONTAINER [CONTAINER...]", "Stop a running container (Send SIGTERM, and then SIGKILL after grace period)")
507
-	nSeconds := cmd.Int("t", 10, "Number of seconds to wait for the container to stop before killing it.")
507
+	nSeconds := cmd.Int([]string{"t", "-time"}, 10, "Number of seconds to wait for the container to stop before killing it.")
508 508
 	if err := cmd.Parse(args); err != nil {
509 509
 		return nil
510 510
 	}
... ...
@@ -531,7 +531,7 @@ func (cli *DockerCli) CmdStop(args ...string) error {
531 531
 
532 532
 func (cli *DockerCli) CmdRestart(args ...string) error {
533 533
 	cmd := cli.Subcmd("restart", "[OPTIONS] CONTAINER [CONTAINER...]", "Restart a running container")
534
-	nSeconds := cmd.Int("t", 10, "Number of seconds to try to stop for before killing the container. Once killed it will then be restarted. Default=10")
534
+	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=10")
535 535
 	if err := cmd.Parse(args); err != nil {
536 536
 		return nil
537 537
 	}
... ...
@@ -574,8 +574,8 @@ func (cli *DockerCli) forwardAllSignals(cid string) chan os.Signal {
574 574
 
575 575
 func (cli *DockerCli) CmdStart(args ...string) error {
576 576
 	cmd := cli.Subcmd("start", "CONTAINER [CONTAINER...]", "Restart a stopped container")
577
-	attach := cmd.Bool("a", false, "Attach container's stdout/stderr and forward all signals to the process")
578
-	openStdin := cmd.Bool("i", false, "Attach container's stdin")
577
+	attach := cmd.Bool([]string{"a", "-attach"}, false, "Attach container's stdout/stderr and forward all signals to the process")
578
+	openStdin := cmd.Bool([]string{"i", "-interactive"}, false, "Attach container's stdin")
579 579
 	if err := cmd.Parse(args); err != nil {
580 580
 		return nil
581 581
 	}
... ...
@@ -660,7 +660,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
660 660
 
661 661
 func (cli *DockerCli) CmdInspect(args ...string) error {
662 662
 	cmd := cli.Subcmd("inspect", "CONTAINER|IMAGE [CONTAINER|IMAGE...]", "Return low-level information on a container/image")
663
-	tmplStr := cmd.String("format", "", "Format the output using the given go template.")
663
+	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template.")
664 664
 	if err := cmd.Parse(args); err != nil {
665 665
 		return nil
666 666
 	}
... ...
@@ -846,8 +846,8 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
846 846
 
847 847
 func (cli *DockerCli) CmdHistory(args ...string) error {
848 848
 	cmd := cli.Subcmd("history", "[OPTIONS] IMAGE", "Show the history of an image")
849
-	quiet := cmd.Bool("q", false, "only show numeric IDs")
850
-	noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
849
+	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "only show numeric IDs")
850
+	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
851 851
 
852 852
 	if err := cmd.Parse(args); err != nil {
853 853
 		return nil
... ...
@@ -906,8 +906,8 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
906 906
 
907 907
 func (cli *DockerCli) CmdRm(args ...string) error {
908 908
 	cmd := cli.Subcmd("rm", "[OPTIONS] CONTAINER [CONTAINER...]", "Remove one or more containers")
909
-	v := cmd.Bool("v", false, "Remove the volumes associated to the container")
910
-	link := cmd.Bool("link", false, "Remove the specified link and not the underlying container")
909
+	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated to the container")
910
+	link := cmd.Bool([]string{"l", "#link", "-link"}, false, "Remove the specified link and not the underlying container")
911 911
 
912 912
 	if err := cmd.Parse(args); err != nil {
913 913
 		return nil
... ...
@@ -1058,7 +1058,7 @@ func (cli *DockerCli) CmdPush(args ...string) error {
1058 1058
 
1059 1059
 func (cli *DockerCli) CmdPull(args ...string) error {
1060 1060
 	cmd := cli.Subcmd("pull", "NAME", "Pull an image or a repository from the registry")
1061
-	tag := cmd.String("t", "", "Download tagged image in repository")
1061
+	tag := cmd.String([]string{"t", "-tag"}, "", "Download tagged image in repository")
1062 1062
 	if err := cmd.Parse(args); err != nil {
1063 1063
 		return nil
1064 1064
 	}
... ...
@@ -1118,11 +1118,11 @@ func (cli *DockerCli) CmdPull(args ...string) error {
1118 1118
 
1119 1119
 func (cli *DockerCli) CmdImages(args ...string) error {
1120 1120
 	cmd := cli.Subcmd("images", "[OPTIONS] [NAME]", "List images")
1121
-	quiet := cmd.Bool("q", false, "only show numeric IDs")
1122
-	all := cmd.Bool("a", false, "show all images (by default filter out the intermediate images used to build)")
1123
-	noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
1124
-	flViz := cmd.Bool("viz", false, "output graph in graphviz format")
1125
-	flTree := cmd.Bool("tree", false, "output graph in tree format")
1121
+	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "only show numeric IDs")
1122
+	all := cmd.Bool([]string{"a", "-all"}, false, "show all images (by default filter out the intermediate images used to build)")
1123
+	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
1124
+	flViz := cmd.Bool([]string{"v", "#viz", "-viz"}, false, "output graph in graphviz format")
1125
+	flTree := cmd.Bool([]string{"t", "#tree", "-tree"}, false, "output graph in tree format")
1126 1126
 
1127 1127
 	if err := cmd.Parse(args); err != nil {
1128 1128
 		return nil
... ...
@@ -1329,14 +1329,14 @@ func displayablePorts(ports []APIPort) string {
1329 1329
 
1330 1330
 func (cli *DockerCli) CmdPs(args ...string) error {
1331 1331
 	cmd := cli.Subcmd("ps", "[OPTIONS]", "List containers")
1332
-	quiet := cmd.Bool("q", false, "Only display numeric IDs")
1333
-	size := cmd.Bool("s", false, "Display sizes")
1334
-	all := cmd.Bool("a", false, "Show all containers. Only running containers are shown by default.")
1335
-	noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
1336
-	nLatest := cmd.Bool("l", false, "Show only the latest created container, include non-running ones.")
1337
-	since := cmd.String("sinceId", "", "Show only containers created since Id, include non-running ones.")
1338
-	before := cmd.String("beforeId", "", "Show only container created before Id, include non-running ones.")
1339
-	last := cmd.Int("n", -1, "Show n last created containers, include non-running ones.")
1332
+	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
1333
+	size := cmd.Bool([]string{"s", "-size"}, false, "Display sizes")
1334
+	all := cmd.Bool([]string{"a", "-all"}, false, "Show all containers. Only running containers are shown by default.")
1335
+	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
1336
+	nLatest := cmd.Bool([]string{"l", "-latest"}, false, "Show only the latest created container, include non-running ones.")
1337
+	since := cmd.String([]string{"#sinceId", "-since-id"}, "", "Show only containers created since Id, include non-running ones.")
1338
+	before := cmd.String([]string{"#beforeId", "-before-id"}, "", "Show only container created before Id, include non-running ones.")
1339
+	last := cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.")
1340 1340
 
1341 1341
 	if err := cmd.Parse(args); err != nil {
1342 1342
 		return nil
... ...
@@ -1418,9 +1418,9 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1418 1418
 
1419 1419
 func (cli *DockerCli) CmdCommit(args ...string) error {
1420 1420
 	cmd := cli.Subcmd("commit", "[OPTIONS] CONTAINER [REPOSITORY[:TAG]]", "Create a new image from a container's changes")
1421
-	flComment := cmd.String("m", "", "Commit message")
1422
-	flAuthor := cmd.String("author", "", "Author (eg. \"John Hannibal Smith <hannibal@a-team.com>\"")
1423
-	flConfig := cmd.String("run", "", "Config automatically applied when the image is run. "+`(ex: -run='{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')`)
1421
+	flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
1422
+	flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (eg. \"John Hannibal Smith <hannibal@a-team.com>\"")
1423
+	flConfig := cmd.String([]string{"#run", "-run"}, "", "Config automatically applied when the image is run. "+`(ex: -run='{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')`)
1424 1424
 	if err := cmd.Parse(args); err != nil {
1425 1425
 		return nil
1426 1426
 	}
... ...
@@ -1470,7 +1470,7 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
1470 1470
 
1471 1471
 func (cli *DockerCli) CmdEvents(args ...string) error {
1472 1472
 	cmd := cli.Subcmd("events", "[OPTIONS]", "Get real time events from the server")
1473
-	since := cmd.String("since", "", "Show previously created events and then stream.")
1473
+	since := cmd.String([]string{"#since", "-since"}, "", "Show previously created events and then stream.")
1474 1474
 	if err := cmd.Parse(args); err != nil {
1475 1475
 		return nil
1476 1476
 	}
... ...
@@ -1557,7 +1557,7 @@ func (cli *DockerCli) CmdDiff(args ...string) error {
1557 1557
 
1558 1558
 func (cli *DockerCli) CmdLogs(args ...string) error {
1559 1559
 	cmd := cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container")
1560
-	follow := cmd.Bool("f", false, "Follow log output")
1560
+	follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
1561 1561
 	if err := cmd.Parse(args); err != nil {
1562 1562
 		return nil
1563 1563
 	}
... ...
@@ -1593,8 +1593,8 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
1593 1593
 
1594 1594
 func (cli *DockerCli) CmdAttach(args ...string) error {
1595 1595
 	cmd := cli.Subcmd("attach", "[OPTIONS] CONTAINER", "Attach to a running container")
1596
-	noStdin := cmd.Bool("nostdin", false, "Do not attach stdin")
1597
-	proxy := cmd.Bool("sig-proxy", true, "Proxify all received signal to the process (even in non-tty mode)")
1596
+	noStdin := cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach stdin")
1597
+	proxy := cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
1598 1598
 	if err := cmd.Parse(args); err != nil {
1599 1599
 		return nil
1600 1600
 	}
... ...
@@ -1657,9 +1657,9 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
1657 1657
 
1658 1658
 func (cli *DockerCli) CmdSearch(args ...string) error {
1659 1659
 	cmd := cli.Subcmd("search", "TERM", "Search the docker index for images")
1660
-	noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
1661
-	trusted := cmd.Bool("trusted", false, "Only show trusted builds")
1662
-	stars := cmd.Int("stars", 0, "Only displays with at least xxx stars")
1660
+	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
1661
+	trusted := cmd.Bool([]string{"t", "#trusted", "-trusted"}, false, "Only show trusted builds")
1662
+	stars := cmd.Int([]string{"s", "#stars", "-stars"}, 0, "Only displays with at least xxx stars")
1663 1663
 	if err := cmd.Parse(args); err != nil {
1664 1664
 		return nil
1665 1665
 	}
... ...
@@ -1712,7 +1712,7 @@ type ports []int
1712 1712
 
1713 1713
 func (cli *DockerCli) CmdTag(args ...string) error {
1714 1714
 	cmd := cli.Subcmd("tag", "[OPTIONS] IMAGE REPOSITORY[:TAG]", "Tag an image into a repository")
1715
-	force := cmd.Bool("f", false, "Force")
1715
+	force := cmd.Bool([]string{"f", "#force", "-force"}, false, "Force")
1716 1716
 	if err := cmd.Parse(args); err != nil {
1717 1717
 		return nil
1718 1718
 	}
... ...
@@ -1766,36 +1766,36 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co
1766 1766
 		flVolumesFrom ListOpts
1767 1767
 		flLxcOpts     ListOpts
1768 1768
 
1769
-		flAutoRemove      = cmd.Bool("rm", false, "Automatically remove the container when it exits (incompatible with -d)")
1770
-		flDetach          = cmd.Bool("d", false, "Detached mode: Run container in the background, print new container id")
1771
-		flNetwork         = cmd.Bool("n", true, "Enable networking for this container")
1772
-		flPrivileged      = cmd.Bool("privileged", false, "Give extended privileges to this container")
1773
-		flPublishAll      = cmd.Bool("P", false, "Publish all exposed ports to the host interfaces")
1774
-		flStdin           = cmd.Bool("i", false, "Keep stdin open even if not attached")
1775
-		flTty             = cmd.Bool("t", false, "Allocate a pseudo-tty")
1776
-		flContainerIDFile = cmd.String("cidfile", "", "Write the container ID to the file")
1777
-		flEntrypoint      = cmd.String("entrypoint", "", "Overwrite the default entrypoint of the image")
1778
-		flHostname        = cmd.String("h", "", "Container host name")
1779
-		flMemoryString    = cmd.String("m", "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
1780
-		flUser            = cmd.String("u", "", "Username or UID")
1781
-		flWorkingDir      = cmd.String("w", "", "Working directory inside the container")
1782
-		flCpuShares       = cmd.Int64("c", 0, "CPU shares (relative weight)")
1769
+		flAutoRemove      = cmd.Bool([]string{"#rm", "-rm"}, false, "Automatically remove the container when it exits (incompatible with -d)")
1770
+		flDetach          = cmd.Bool([]string{"d", "-detach"}, false, "Detached mode: Run container in the background, print new container id")
1771
+		flNetwork         = cmd.Bool([]string{"n", "-networking"}, true, "Enable networking for this container")
1772
+		flPrivileged      = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
1773
+		flPublishAll      = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to the host interfaces")
1774
+		flStdin           = cmd.Bool([]string{"i", "-interactive"}, false, "Keep stdin open even if not attached")
1775
+		flTty             = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-tty")
1776
+		flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
1777
+		flEntrypoint      = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default entrypoint of the image")
1778
+		flHostname        = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
1779
+		flMemoryString    = cmd.String([]string{"m", "-memory"}, "", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)")
1780
+		flUser            = cmd.String([]string{"u", "-username"}, "", "Username or UID")
1781
+		flWorkingDir      = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
1782
+		flCpuShares       = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
1783 1783
 
1784 1784
 		// For documentation purpose
1785
-		_ = cmd.Bool("sig-proxy", true, "Proxify all received signal to the process (even in non-tty mode)")
1786
-		_ = cmd.String("name", "", "Assign a name to the container")
1785
+		_ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
1786
+		_ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container")
1787 1787
 	)
1788 1788
 
1789
-	cmd.Var(&flAttach, "a", "Attach to stdin, stdout or stderr.")
1790
-	cmd.Var(&flVolumes, "v", "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
1791
-	cmd.Var(&flLinks, "link", "Add link to another container (name:alias)")
1792
-	cmd.Var(&flEnv, "e", "Set environment variables")
1789
+	cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to stdin, stdout or stderr.")
1790
+	cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)")
1791
+	cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container (name:alias)")
1792
+	cmd.Var(&flEnv, []string{"e", "-env"}, "Set environment variables")
1793 1793
 
1794
-	cmd.Var(&flPublish, "p", fmt.Sprintf("Publish a container's port to the host (format: %s) (use 'docker port' to see the actual mapping)", PortSpecTemplateFormat))
1795
-	cmd.Var(&flExpose, "expose", "Expose a port from the container without publishing it to your host")
1796
-	cmd.Var(&flDns, "dns", "Set custom dns servers")
1797
-	cmd.Var(&flVolumesFrom, "volumes-from", "Mount volumes from the specified container(s)")
1798
-	cmd.Var(&flLxcOpts, "lxc-conf", "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
1794
+	cmd.Var(&flPublish, []string{"p", "-publish"}, fmt.Sprintf("Publish a container's port to the host (format: %s) (use 'docker port' to see the actual mapping)", PortSpecTemplateFormat))
1795
+	cmd.Var(&flExpose, []string{"#expose", "-expose"}, "Expose a port from the container without publishing it to your host")
1796
+	cmd.Var(&flDns, []string{"#dns", "-dns"}, "Set custom dns servers")
1797
+	cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
1798
+	cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options -lxc-conf=\"lxc.cgroup.cpuset.cpus = 0,1\"")
1799 1799
 
1800 1800
 	if err := cmd.Parse(args); err != nil {
1801 1801
 		return nil, nil, cmd, err
... ...
@@ -1892,7 +1892,7 @@ func parseRun(cmd *flag.FlagSet, args []string, capabilities *Capabilities) (*Co
1892 1892
 	// Merge in exposed ports to the map of published ports
1893 1893
 	for _, e := range flExpose.GetAll() {
1894 1894
 		if strings.Contains(e, ":") {
1895
-			return nil, nil, cmd, fmt.Errorf("Invalid port format for -expose: %s", e)
1895
+			return nil, nil, cmd, fmt.Errorf("Invalid port format for --expose: %s", e)
1896 1896
 		}
1897 1897
 		p := NewPort(splitProtoPort(e))
1898 1898
 		if _, exists := ports[p]; !exists {
... ...
@@ -25,7 +25,7 @@ __docker_containers_all()
25 25
 {
26 26
 	local containers
27 27
 	containers="$( docker ps -a -q )"
28
-	names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
28
+	names="$( docker inspect --format '{{.Name}}' $containers | sed 's,^/,,' )"
29 29
 	COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
30 30
 }
31 31
 
... ...
@@ -33,7 +33,7 @@ __docker_containers_running()
33 33
 {
34 34
 	local containers
35 35
 	containers="$( docker ps -q )"
36
-	names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
36
+	names="$( docker inspect --format '{{.Name}}' $containers | sed 's,^/,,' )"
37 37
 	COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
38 38
 }
39 39
 
... ...
@@ -41,7 +41,7 @@ __docker_containers_stopped()
41 41
 {
42 42
 	local containers
43 43
 	containers="$( comm -13 <(docker ps -q | sort -u) <(docker ps -a -q | sort -u) )"
44
-	names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
44
+	names="$( docker inspect --format '{{.Name}}' $containers | sed 's,^/,,' )"
45 45
 	COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) )
46 46
 }
47 47
 
... ...
@@ -73,7 +73,7 @@ __docker_containers_and_images()
73 73
 {
74 74
 	local containers images
75 75
 	containers="$( docker ps -a -q )"
76
-	names="$( docker inspect -format '{{.Name}}' $containers | sed 's,^/,,' )"
76
+	names="$( docker inspect --format '{{.Name}}' $containers | sed 's,^/,,' )"
77 77
 	images="$( docker images | awk 'NR>1{print $1":"$2}' )"
78 78
 	COMPREPLY=( $( compgen -W "$images $names $containers" -- "$cur" ) )
79 79
 	__ltrim_colon_completions "$cur"
... ...
@@ -118,7 +118,7 @@ _docker_build()
118 118
 
119 119
 	case "$cur" in
120 120
 		-*)
121
-			COMPREPLY=( $( compgen -W "-no-cache -t -q -rm" -- "$cur" ) )
121
+			COMPREPLY=( $( compgen -W "--no-cache -t -q --rm" -- "$cur" ) )
122 122
 			;;
123 123
 		*)
124 124
 			_filedir
... ...
@@ -138,7 +138,7 @@ _docker_commit()
138 138
 
139 139
 	case "$cur" in
140 140
 		-*)
141
-			COMPREPLY=( $( compgen -W "-author -m -run" -- "$cur" ) )
141
+			COMPREPLY=( $( compgen -W "--author -m --run" -- "$cur" ) )
142 142
 			;;
143 143
 		*)
144 144
 			local counter=$cpos
... ...
@@ -191,7 +191,7 @@ _docker_events()
191 191
 
192 192
 	case "$cur" in
193 193
 		-*)
194
-			COMPREPLY=( $( compgen -W "-since" -- "$cur" ) )
194
+			COMPREPLY=( $( compgen -W "--since" -- "$cur" ) )
195 195
 			;;
196 196
 		*)
197 197
 			;;
... ...
@@ -223,7 +223,7 @@ _docker_images()
223 223
 {
224 224
 	case "$cur" in
225 225
 		-*)
226
-			COMPREPLY=( $( compgen -W "-a -notrunc -q -viz" -- "$cur" ) )
226
+			COMPREPLY=( $( compgen -W "-a --no-trunc -q --viz" -- "$cur" ) )
227 227
 			;;
228 228
 		*)
229 229
 			local counter=$cpos
... ...
@@ -308,7 +308,7 @@ _docker_port()
308 308
 _docker_ps()
309 309
 {
310 310
 	case "$prev" in
311
-		-beforeId|-n|-sinceId)
311
+		-before-id|-n|-since-id)
312 312
 			return
313 313
 			;;
314 314
 		*)
... ...
@@ -317,7 +317,7 @@ _docker_ps()
317 317
 
318 318
 	case "$cur" in
319 319
 		-*)
320
-			COMPREPLY=( $( compgen -W "-a -beforeId -l -n -notrunc -q -s -sinceId" -- "$cur" ) )
320
+			COMPREPLY=( $( compgen -W "-a --before-id -l -n --no-trunc -q -s --since-id" -- "$cur" ) )
321 321
 			;;
322 322
 		*)
323 323
 			;;
... ...
@@ -388,13 +388,13 @@ _docker_rmi()
388 388
 _docker_run()
389 389
 {
390 390
 	case "$prev" in
391
-		-cidfile)
391
+		--cidfile)
392 392
 			_filedir
393 393
 			;;
394
-		-volumes-from)
394
+		--volumes-from)
395 395
 			__docker_containers_all
396 396
 			;;
397
-		-a|-c|-dns|-e|-entrypoint|-h|-lxc-conf|-m|-p|-u|-v|-w)
397
+		-a|-c|--dns|-e|--entrypoint|-h|--lxc-conf|-m|-p|-u|-v|-w)
398 398
 			return
399 399
 			;;
400 400
 		*)
... ...
@@ -403,13 +403,13 @@ _docker_run()
403 403
 
404 404
 	case "$cur" in
405 405
 		-*)
406
-			COMPREPLY=( $( compgen -W "-a -c -cidfile -d -dns -e -entrypoint -h -i -lxc-conf -m -n -p -privileged -t -u -v -volumes-from -w" -- "$cur" ) )
406
+			COMPREPLY=( $( compgen -W "-a -c --cidfile -d --dns -e --entrypoint -h -i --lxc-conf -m -n -p --privileged -t -u -v --volumes-from -w" -- "$cur" ) )
407 407
 			;;
408 408
 		*)
409 409
 			local counter=$cpos
410 410
 			while [ $counter -le $cword ]; do
411 411
 				case "${words[$counter]}" in
412
-					-a|-c|-cidfile|-dns|-e|-entrypoint|-h|-lxc-conf|-m|-p|-u|-v|-volumes-from|-w)
412
+					-a|-c|--cidfile|--dns|-e|--entrypoint|-h|--lxc-conf|-m|-p|-u|-v|--volumes-from|-w)
413 413
 						(( counter++ ))
414 414
 						;;
415 415
 					-*)
... ...
@@ -430,7 +430,7 @@ _docker_run()
430 430
 
431 431
 _docker_search()
432 432
 {
433
-	COMPREPLY=( $( compgen -W "-notrunc" "-stars" "-trusted" -- "$cur" ) )
433
+	COMPREPLY=( $( compgen -W "--no-trunc" "--stars" "--trusted" -- "$cur" ) )
434 434
 }
435 435
 
436 436
 _docker_start()
... ...
@@ -174,7 +174,7 @@ __docker_subcommand () {
174 174
         (ps)
175 175
             _arguments '-a[Show all containers. Only running containers are shown by default]' \
176 176
                 '-h[Show help]' \
177
-                '-beforeId=-[Show only container created before Id, include non-running one]:containers:__docker_containers' \
177
+                '-before-id=-[Show only container created before Id, include non-running one]:containers:__docker_containers' \
178 178
             '-n=-[Show n last created containers, include non-running one]:n:(1 5 10 25 50)'
179 179
             ;;
180 180
         (tag)
... ...
@@ -189,9 +189,9 @@ __docker_subcommand () {
189 189
                 '-a=-[Attach to stdin, stdout or stderr]:toggle:(true false)' \
190 190
                 '-c=-[CPU shares (relative weight)]:CPU shares: ' \
191 191
                 '-d[Detached mode: leave the container running in the background]' \
192
-                '*-dns=[Set custom dns servers]:dns server: ' \
192
+                '*--dns=[Set custom dns servers]:dns server: ' \
193 193
                 '*-e=[Set environment variables]:environment variable: ' \
194
-                '-entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
194
+                '--entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
195 195
                 '-h=-[Container host name]:hostname:_hosts' \
196 196
                 '-i[Keep stdin open even if not attached]' \
197 197
                 '-m=-[Memory limit (in bytes)]:limit: ' \
... ...
@@ -199,7 +199,7 @@ __docker_subcommand () {
199 199
                 '-t=-[Allocate a pseudo-tty]:toggle:(true false)' \
200 200
                 '-u=-[Username or UID]:user:_users' \
201 201
                 '*-v=-[Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)]:volume: '\
202
-                '-volumes-from=-[Mount volumes from the specified container]:volume: ' \
202
+                '--volumes-from=-[Mount volumes from the specified container]:volume: ' \
203 203
                 '(-):images:__docker_images' \
204 204
                 '(-):command: _command_names -e' \
205 205
                 '*::arguments: _normal'
... ...
@@ -1,10 +1,10 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"flag"
5 4
 	"fmt"
6 5
 	"github.com/dotcloud/docker"
7 6
 	"github.com/dotcloud/docker/engine"
7
+	flag "github.com/dotcloud/docker/pkg/mflag"
8 8
 	"github.com/dotcloud/docker/sysinit"
9 9
 	"github.com/dotcloud/docker/utils"
10 10
 	"log"
... ...
@@ -25,25 +25,25 @@ func main() {
25 25
 	}
26 26
 
27 27
 	var (
28
-		flVersion            = flag.Bool("v", false, "Print version information and quit")
29
-		flDaemon             = flag.Bool("d", false, "Enable daemon mode")
30
-		flDebug              = flag.Bool("D", false, "Enable debug mode")
31
-		flAutoRestart        = flag.Bool("r", true, "Restart previously running containers")
32
-		bridgeName           = flag.String("b", "", "Attach containers to a pre-existing network bridge; use 'none' to disable container networking")
33
-		bridgeIp             = flag.String("bip", "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
34
-		pidfile              = flag.String("p", "/var/run/docker.pid", "Path to use for daemon PID file")
35
-		flRoot               = flag.String("g", "/var/lib/docker", "Path to use as the root of the docker runtime")
36
-		flEnableCors         = flag.Bool("api-enable-cors", false, "Enable CORS headers in the remote API")
28
+		flVersion            = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit")
29
+		flDaemon             = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
30
+		flDebug              = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
31
+		flAutoRestart        = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers")
32
+		bridgeName           = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge; use 'none' to disable container networking")
33
+		bridgeIp             = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
34
+		pidfile              = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
35
+		flRoot               = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the docker runtime")
36
+		flEnableCors         = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
37 37
 		flDns                = docker.NewListOpts(docker.ValidateIp4Address)
38
-		flEnableIptables     = flag.Bool("iptables", true, "Disable docker's addition of iptables rules")
39
-		flDefaultIp          = flag.String("ip", "0.0.0.0", "Default IP address to use when binding container ports")
40
-		flInterContainerComm = flag.Bool("icc", true, "Enable inter-container communication")
41
-		flGraphDriver        = flag.String("s", "", "Force the docker runtime to use a specific storage driver")
38
+		flEnableIptables     = flag.Bool([]string{"#iptables", "-iptables"}, true, "Disable docker's addition of iptables rules")
39
+		flDefaultIp          = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports")
40
+		flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication")
41
+		flGraphDriver        = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver")
42 42
 		flHosts              = docker.NewListOpts(docker.ValidateHost)
43
-		flMtu                = flag.Int("mtu", docker.DefaultNetworkMtu, "Set the containers network mtu")
43
+		flMtu                = flag.Int([]string{"#mtu", "-mtu"}, docker.DefaultNetworkMtu, "Set the containers network mtu")
44 44
 	)
45
-	flag.Var(&flDns, "dns", "Force docker to use specific DNS servers")
46
-	flag.Var(&flHosts, "H", "Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise")
45
+	flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers")
46
+	flag.Var(&flHosts, []string{"H", "-host"}, "Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise")
47 47
 
48 48
 	flag.Parse()
49 49
 
... ...
@@ -62,7 +62,7 @@ func main() {
62 62
 	}
63 63
 
64 64
 	if *bridgeName != "" && *bridgeIp != "" {
65
-		log.Fatal("You specified -b & -bip, mutually exclusive options. Please specify only one.")
65
+		log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.")
66 66
 	}
67 67
 
68 68
 	if *flDebug {
... ...
@@ -41,7 +41,7 @@ This time, we're requesting shared access to ``$COUCH1``'s volumes.
41 41
 
42 42
 .. code-block:: bash
43 43
 
44
-    COUCH2=$(sudo docker run -d -p 5984 -volumes-from $COUCH1 shykes/couchdb:2013-05-03)
44
+    COUCH2=$(sudo docker run -d -p 5984 --volumes-from $COUCH1 shykes/couchdb:2013-05-03)
45 45
 
46 46
 Browse data on the second database
47 47
 ----------------------------------
... ...
@@ -43,7 +43,7 @@ container. The ``BUILD_JOB`` environment variable will be set with the new conta
43 43
     [...]
44 44
 
45 45
 While this container is running, we can attach to the new container to
46
-see what is going on. The flag ``-sig-proxy`` set as ``false`` allows you to connect and
46
+see what is going on. The flag ``--sig-proxy`` set as ``false`` allows you to connect and
47 47
 disconnect (Ctrl-C) to it without stopping the container.
48 48
 
49 49
 .. code-block:: bash
... ...
@@ -44,7 +44,7 @@ use a container link to provide access to our Redis database.
44 44
 
45 45
 .. code-block:: bash
46 46
 
47
-    sudo docker run -name redis -d <your username>/redis
47
+    sudo docker run --name redis -d <your username>/redis
48 48
 
49 49
 Create your web application container
50 50
 -------------------------------------
... ...
@@ -56,7 +56,7 @@ Redis instance running inside that container to only this container.
56 56
 
57 57
 .. code-block:: bash
58 58
 
59
-    sudo docker run -link redis:db -i -t ubuntu:12.10 /bin/bash
59
+    sudo docker run --link redis:db -i -t ubuntu:12.10 /bin/bash
60 60
 
61 61
 Once inside our freshly created container we need to install Redis to get the 
62 62
 ``redis-cli`` binary to test our connection.
... ...
@@ -26,22 +26,21 @@ To list available commands, either run ``docker`` with no parameters or execute
26 26
 ::
27 27
 
28 28
     Usage of docker:
29
-      -D=false: Enable debug mode
30
-      -H=[unix:///var/run/docker.sock]: tcp://[host[:port]] to bind or unix://[/path/to/socket] to use. When host=[0.0.0.0], port=[4243] or path=[/var/run/docker.sock] is omitted, default values are used.
31
-      -api-enable-cors=false: Enable CORS headers in the remote API
32
-      -b="": Attach containers to a pre-existing network bridge; use 'none' to disable container networking
33
-      -bip="": Use the provided CIDR notation address for the dynamically created bridge (docker0); Mutually exclusive of -b
34
-      -d=false: Enable daemon mode
35
-      -dns="": Force docker to use specific DNS servers
36
-      -g="/var/lib/docker": Path to use as the root of the docker runtime
37
-      -icc=true: Enable inter-container communication
38
-      -ip="0.0.0.0": Default IP address to use when binding container ports
39
-      -iptables=true: Disable docker's addition of iptables rules
40
-      -mtu=1500: Set the containers network mtu
41
-      -p="/var/run/docker.pid": Path to use for daemon PID file
42
-      -r=true: Restart previously running containers
43
-      -s="": Force the docker runtime to use a specific storage driver
44
-      -v=false: Print version information and quit
29
+      -D, --debug=false: Enable debug mode
30
+      -H, --host=[]: Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise
31
+      --api-enable-cors=false: Enable CORS headers in the remote API
32
+      -b, --bridge="": Attach containers to a pre-existing network bridge; use 'none' to disable container networking
33
+      --bip="": Use this CIDR notation address for the network bridge's IP, not compatible with -b
34
+      -d, --daemon=false: Enable daemon mode
35
+      --dns=[]: Force docker to use specific DNS servers
36
+      -g, --graph="/var/lib/docker": Path to use as the root of the docker runtime
37
+      --icc=true: Enable inter-container communication
38
+      --ip="0.0.0.0": Default IP address to use when binding container ports
39
+      --iptables=true: Disable docker's addition of iptables rules
40
+      -p, --pidfile="/var/run/docker.pid": Path to use for daemon PID file
41
+      -r, --restart=true: Restart previously running containers
42
+      -s, --storage-driver="": Force the docker runtime to use a specific storage driver
43
+      -v, --version=false: Print version information and quit
45 44
 
46 45
 The Docker daemon is the persistent process that manages containers.  Docker uses the same binary for both the 
47 46
 daemon and client.  To run the daemon you provide the ``-d`` flag.
... ...
@@ -75,8 +74,8 @@ the ``-H`` flag for the client.
75 75
 
76 76
     Attach to a running container.
77 77
 
78
-      -nostdin=false: Do not attach stdin
79
-      -sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
78
+      --no-stdin=false: Do not attach stdin
79
+      --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
80 80
 
81 81
 You can detach from the container again (and leave it running) with
82 82
 ``CTRL-c`` (for a quiet exit) or ``CTRL-\`` to get a stacktrace of
... ...
@@ -135,11 +134,11 @@ Examples:
135 135
 
136 136
     Usage: docker build [OPTIONS] PATH | URL | -
137 137
     Build a new container image from the source code at PATH
138
-      -t="": Repository name (and optionally a tag) to be applied 
138
+      -t, --time="": Repository name (and optionally a tag) to be applied 
139 139
              to the resulting image in case of success.
140
-      -q=false: Suppress verbose build output.
141
-      -no-cache: Do not use the cache when building the image.
142
-      -rm: Remove intermediate containers after a successful build
140
+      -q, --quiet=false: Suppress verbose build output.
141
+      --no-cache: Do not use the cache when building the image.
142
+      --rm: Remove intermediate containers after a successful build
143 143
 
144 144
 The files at ``PATH`` or ``URL`` are called the "context" of the build. The
145 145
 build process may refer to any of the files in the context, for example when
... ...
@@ -233,9 +232,9 @@ by using the ``git://`` schema.
233 233
 
234 234
     Create a new image from a container's changes
235 235
 
236
-      -m="": Commit message
237
-      -author="": Author (eg. "John Hannibal Smith <hannibal@a-team.com>"
238
-      -run="": Configuration to be applied when the image is launched with `docker run`.
236
+      -m, --message="": Commit message
237
+      -a, --author="": Author (eg. "John Hannibal Smith <hannibal@a-team.com>"
238
+      --run="": Configuration to be applied when the image is launched with `docker run`.
239 239
                (ex: -run='{"Cmd": ["cat", "/world"], "PortSpecs": ["22"]}')
240 240
 
241 241
 .. _cli_commit_examples:
... ...
@@ -279,7 +278,7 @@ run ``ls /etc``.
279 279
 Full -run example
280 280
 .................
281 281
 
282
-The ``-run`` JSON hash changes the ``Config`` section when running ``docker inspect CONTAINERID``
282
+The ``--run`` JSON hash changes the ``Config`` section when running ``docker inspect CONTAINERID``
283 283
 or ``config`` when running ``docker inspect IMAGEID``.
284 284
 
285 285
 (Multiline is okay within a single quote ``'``)
... ...
@@ -379,7 +378,7 @@ For example:
379 379
 
380 380
     Get real time events from the server
381 381
 
382
-    -since="": Show previously created events and then stream.
382
+    --since="": Show previously created events and then stream.
383 383
                (either seconds since epoch, or date string as below)
384 384
 
385 385
 .. _cli_events_example:
... ...
@@ -459,8 +458,8 @@ For example:
459 459
 
460 460
     Show the history of an image
461 461
 
462
-      -notrunc=false: Don't truncate output
463
-      -q=false: only show numeric IDs
462
+      --no-trunc=false: Don't truncate output
463
+      -q, --quiet=false: only show numeric IDs
464 464
 
465 465
 To see how the ``docker:latest`` image was built:
466 466
 
... ...
@@ -507,11 +506,11 @@ To see how the ``docker:latest`` image was built:
507 507
 
508 508
     List images
509 509
 
510
-      -a=false: show all images (by default filter out the intermediate images used to build)
511
-      -notrunc=false: Don't truncate output
512
-      -q=false: only show numeric IDs
513
-      -tree=false: output graph in tree format
514
-      -viz=false: output graph in graphviz format
510
+      -a, --all=false: show all images (by default filter out the intermediate images used to build)
511
+      --no-trunc=false: Don't truncate output
512
+      -q, --quiet=false: only show numeric IDs
513
+      --tree=false: output graph in tree format
514
+      --viz=false: output graph in graphviz format
515 515
 
516 516
 Listing the most recently created images
517 517
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... ...
@@ -535,7 +534,7 @@ Listing the full length image IDs
535 535
 
536 536
 .. code-block:: bash
537 537
 
538
-	$ sudo docker images -notrunc | head
538
+	$ sudo docker images --no-trunc | head
539 539
 	REPOSITORY                    TAG                 IMAGE ID                                                           CREATED             VIRTUAL SIZE
540 540
 	<none>                        <none>              77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182   19 hours ago        1.089 GB
541 541
 	committest                    latest              b6fa739cedf5ea12a620a439402b6004d057da800f91c7524b5086a5e4749c9f   19 hours ago        1.089 GB
... ...
@@ -552,7 +551,7 @@ Displaying images visually
552 552
 
553 553
 .. code-block:: bash
554 554
 
555
-    $ sudo docker images -viz | dot -Tpng -o docker.png
555
+    $ sudo docker images --viz | dot -Tpng -o docker.png
556 556
 
557 557
 .. image:: docker_images.gif
558 558
    :alt: Example inheritance graph of Docker images.
... ...
@@ -563,7 +562,7 @@ Displaying image hierarchy
563 563
 
564 564
 .. code-block:: bash
565 565
 
566
-    $ sudo docker images -tree
566
+    $ sudo docker images --tree
567 567
 
568 568
     ├─8dbd9e392a96 Size: 131.5 MB (virtual 131.5 MB) Tags: ubuntu:12.04,ubuntu:latest,ubuntu:precise
569 569
     └─27cf78414709 Size: 180.1 MB (virtual 180.1 MB)
... ...
@@ -702,7 +701,7 @@ Insert file from GitHub
702 702
 
703 703
     Return low-level information on a container/image
704 704
 
705
-      -format="": Format the output using the given go template.
705
+      -f, --format="": Format the output using the given go template.
706 706
 
707 707
 By default, this will render all results in a JSON array.  If a format
708 708
 is specified, the given template will be executed for each result.
... ...
@@ -721,7 +720,7 @@ fairly straightforward manner.
721 721
 
722 722
 .. code-block:: bash
723 723
 
724
-    $ sudo docker inspect -format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID
724
+    $ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID
725 725
 
726 726
 List All Port Bindings
727 727
 ......................
... ...
@@ -790,9 +789,9 @@ Known Issues (kill)
790 790
 
791 791
     Register or Login to the docker registry server
792 792
 
793
-    -e="": email
794
-    -p="": password
795
-    -u="": username
793
+    -e, --email="": email
794
+    -p, --password="": password
795
+    -u, --username="": username
796 796
 
797 797
     If you want to login to a private registry you can
798 798
     specify this by adding the server name.
... ...
@@ -812,12 +811,14 @@ Known Issues (kill)
812 812
 
813 813
     Fetch the logs of a container
814 814
 
815
+    -f, --follow=false: Follow log output
816
+
815 817
 The ``docker logs`` command is a convenience which batch-retrieves whatever
816 818
 logs are present at the time of execution. This does not guarantee execution
817 819
 order when combined with a ``docker run`` (i.e. your run may not have generated
818 820
 any logs at the time you execute ``docker logs``).
819 821
 
820
-The ``docker logs -f`` command combines ``docker logs`` and ``docker attach``:
822
+The ``docker logs --follow`` command combines ``docker logs`` and ``docker attach``:
821 823
 it will first return all logs from the beginning and then continue streaming
822 824
 new output from the container's stdout and stderr.
823 825
 
... ...
@@ -845,9 +846,9 @@ new output from the container's stdout and stderr.
845 845
 
846 846
     List containers
847 847
 
848
-      -a=false: Show all containers. Only running containers are shown by default.
849
-      -notrunc=false: Don't truncate output
850
-      -q=false: Only display numeric IDs
848
+      -a, --all=false: Show all containers. Only running containers are shown by default.
849
+      --no-trunc=false: Don't truncate output
850
+      -q, --quiet=false: Only display numeric IDs
851 851
 
852 852
 Running ``docker ps`` showing 2 linked containers.
853 853
 
... ...
@@ -903,7 +904,7 @@ Running ``docker ps`` showing 2 linked containers.
903 903
     Usage: docker rm [OPTIONS] CONTAINER
904 904
 
905 905
     Remove one or more containers
906
-        -link="": Remove the link instead of the actual container
906
+        --link="": Remove the link instead of the actual container
907 907
 
908 908
 Known Issues (rm)
909 909
 ~~~~~~~~~~~~~~~~~
... ...
@@ -926,7 +927,7 @@ This will remove the container referenced under the link ``/redis``.
926 926
 
927 927
 .. code-block:: bash
928 928
 
929
-    $ sudo docker rm -link /webapp/redis
929
+    $ sudo docker rm --link /webapp/redis
930 930
     /webapp/redis
931 931
 
932 932
 
... ...
@@ -996,31 +997,31 @@ image is removed.
996 996
 
997 997
     Run a command in a new container
998 998
 
999
-      -a=map[]: Attach to stdin, stdout or stderr
1000
-      -c=0: CPU shares (relative weight)
1001
-      -cidfile="": Write the container ID to the file
1002
-      -d=false: Detached mode: Run container in the background, print new container id
1003
-      -e=[]: Set environment variables
1004
-      -h="": Container host name
1005
-      -i=false: Keep stdin open even if not attached
1006
-      -privileged=false: Give extended privileges to this container
1007
-      -m="": Memory limit (format: <number><optional unit>, where unit = b, k, m or g)
1008
-      -n=true: Enable networking for this container
1009
-      -p=[]: Map a network port to the container
1010
-      -rm=false: Automatically remove the container when it exits (incompatible with -d)
1011
-      -t=false: Allocate a pseudo-tty
1012
-      -u="": Username or UID
1013
-      -dns=[]: Set custom dns servers for the container
1014
-      -v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
1015
-      -volumes-from="": Mount all volumes from the given container(s)
1016
-      -entrypoint="": Overwrite the default entrypoint set by the image
1017
-      -w="": Working directory inside the container
1018
-      -lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
1019
-      -sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
1020
-      -expose=[]: Expose a port from the container without publishing it to your host
1021
-      -link="": Add link to another container (name:alias)
1022
-      -name="": Assign the specified name to the container. If no name is specific docker will generate a random name
1023
-      -P=false: Publish all exposed ports to the host interfaces
999
+      -a, --attach=map[]: Attach to stdin, stdout or stderr
1000
+      -c, --cpu-shares=0: CPU shares (relative weight)
1001
+      --cidfile="": Write the container ID to the file
1002
+      -d, --detach=false: Detached mode: Run container in the background, print new container id
1003
+      -e, --env=[]: Set environment variables
1004
+      -h, --host="": Container host name
1005
+      -i, --interactive=false: Keep stdin open even if not attached
1006
+      --privileged=false: Give extended privileges to this container
1007
+      -m, --memory="": Memory limit (format: <number><optional unit>, where unit = b, k, m or g)
1008
+      -n, --networking=true: Enable networking for this container
1009
+      -p, --publish=[]: Map a network port to the container
1010
+      --rm=false: Automatically remove the container when it exits (incompatible with -d)
1011
+      -t, --tty=false: Allocate a pseudo-tty
1012
+      -u, --username="": Username or UID
1013
+      --dns=[]: Set custom dns servers for the container
1014
+      -v, --volume=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro]. If "container-dir" is missing, then docker creates a new volume.
1015
+      --volumes-from="": Mount all volumes from the given container(s)
1016
+      --entrypoint="": Overwrite the default entrypoint set by the image
1017
+      -w, --workdir="": Working directory inside the container
1018
+      --lxc-conf=[]: Add custom lxc options -lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
1019
+      --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode)
1020
+      --expose=[]: Expose a port from the container without publishing it to your host
1021
+      --link="": Add link to another container (name:alias)
1022
+      --name="": Assign the specified name to the container. If no name is specific docker will generate a random name
1023
+      -P, --publish-all=false: Publish all exposed ports to the host interfaces
1024 1024
 
1025 1025
 The ``docker run`` command first ``creates`` a writeable container layer over
1026 1026
 the specified image, and then ``starts`` it using the specified command. That
... ...
@@ -1042,7 +1043,7 @@ Examples:
1042 1042
 
1043 1043
 .. code-block:: bash
1044 1044
 
1045
-    $ sudo docker run -cidfile /tmp/docker_test.cid ubuntu echo "test"
1045
+    $ sudo docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"
1046 1046
 
1047 1047
 This will create a container and print ``test`` to the console. The
1048 1048
 ``cidfile`` flag makes Docker attempt to create a new file and write the
... ...
@@ -1051,7 +1052,7 @@ error. Docker will close this file when ``docker run`` exits.
1051 1051
 
1052 1052
 .. code-block:: bash
1053 1053
 
1054
-   $ sudo docker run -t -i -rm ubuntu bash
1054
+   $ sudo docker run -t -i --rm ubuntu bash
1055 1055
    root@bc338942ef20:/# mount -t tmpfs none /mnt
1056 1056
    mount: permission denied
1057 1057
 
... ...
@@ -1063,7 +1064,7 @@ allow it to run:
1063 1063
 
1064 1064
 .. code-block:: bash
1065 1065
 
1066
-   $ sudo docker run -privileged ubuntu bash
1066
+   $ sudo docker run --privileged ubuntu bash
1067 1067
    root@50e3f57e16e6:/# mount -t tmpfs none /mnt
1068 1068
    root@50e3f57e16e6:/# df -h
1069 1069
    Filesystem      Size  Used Avail Use% Mounted on
... ...
@@ -1104,7 +1105,7 @@ in Docker.
1104 1104
 
1105 1105
 .. code-block:: bash
1106 1106
 
1107
-    $ sudo docker run -expose 80 ubuntu bash
1107
+    $ sudo docker run --expose 80 ubuntu bash
1108 1108
 
1109 1109
 This exposes port ``80`` of the container for use within a link without
1110 1110
 publishing the port to the host system's interfaces. :ref:`port_redirection`
... ...
@@ -1112,28 +1113,28 @@ explains in detail how to manipulate ports in Docker.
1112 1112
 
1113 1113
 .. code-block:: bash
1114 1114
 
1115
-    $ sudo docker run -name console -t -i ubuntu bash
1115
+    $ sudo docker run --name console -t -i ubuntu bash
1116 1116
 
1117 1117
 This will create and run a new container with the container name
1118 1118
 being ``console``.
1119 1119
 
1120 1120
 .. code-block:: bash
1121 1121
 
1122
-    $ sudo docker run -link /redis:redis -name console ubuntu bash
1122
+    $ sudo docker run --link /redis:redis --name console ubuntu bash
1123 1123
 
1124
-The ``-link`` flag will link the container named ``/redis`` into the
1124
+The ``--link`` flag will link the container named ``/redis`` into the
1125 1125
 newly created container with the alias ``redis``.  The new container
1126 1126
 can access the network and environment of the redis container via
1127
-environment variables.  The ``-name`` flag will assign the name ``console``
1127
+environment variables.  The ``--name`` flag will assign the name ``console``
1128 1128
 to the newly created container.
1129 1129
 
1130 1130
 .. code-block:: bash
1131 1131
 
1132
-   $ sudo docker run -volumes-from 777f7dc92da7,ba8c0c54f0f2:ro -i -t ubuntu pwd
1132
+   $ sudo docker run --volumes-from 777f7dc92da7,ba8c0c54f0f2:ro -i -t ubuntu pwd
1133 1133
 
1134
-The ``-volumes-from`` flag mounts all the defined volumes from the
1134
+The ``--volumes-from`` flag mounts all the defined volumes from the
1135 1135
 referenced containers. Containers can be specified by a comma seperated
1136
-list or by repetitions of the ``-volumes-from`` argument. The container
1136
+list or by repetitions of the ``--volumes-from`` argument. The container
1137 1137
 ID may be optionally suffixed with ``:ro`` or ``:rw`` to mount the volumes in
1138 1138
 read-only or read-write mode, respectively. By default, the volumes are mounted
1139 1139
 in the same mode (read write or read only) as the reference container.
... ...
@@ -1143,11 +1144,11 @@ A complete example
1143 1143
 
1144 1144
 .. code-block:: bash
1145 1145
 
1146
-   $ sudo docker run -d -name static static-web-files sh
1147
-   $ sudo docker run -d -expose=8098 -name riak riakserver
1148
-   $ sudo docker run -d -m 100m -e DEVELOPMENT=1 -e BRANCH=example-code -v $(pwd):/app/bin:ro -name app appserver
1149
-   $ sudo docker run -d -p 1443:443 -dns=dns.dev.org -v /var/log/httpd -volumes-from static -link riak -link app -h www.sven.dev.org -name web webserver
1150
-   $ sudo docker run -t -i -rm -volumes-from web -w /var/log/httpd busybox tail -f access.log
1146
+   $ sudo docker run -d --name static static-web-files sh
1147
+   $ sudo docker run -d --expose=8098 --name riak riakserver
1148
+   $ sudo docker run -d -m 100m -e DEVELOPMENT=1 -e BRANCH=example-code -v $(pwd):/app/bin:ro --name app appserver
1149
+   $ sudo docker run -d -p 1443:443 --dns=dns.dev.org -v /var/log/httpd --volumes-from static --link riak --link app -h www.sven.dev.org --name web webserver
1150
+   $ sudo docker run -t -i --rm --volumes-from web -w /var/log/httpd busybox tail -f access.log
1151 1151
 
1152 1152
 This example shows 5 containers that might be set up to test a web application change:
1153 1153
 
... ...
@@ -1181,9 +1182,9 @@ This example shows 5 containers that might be set up to test a web application c
1181 1181
 
1182 1182
     Search the docker index for images
1183 1183
 
1184
-     -notrunc=false: Don't truncate output
1185
-     -stars=0: Only displays with at least xxx stars
1186
-     -trusted=false: Only show trusted builds
1184
+     --no-trunc=false: Don't truncate output
1185
+     -s, --stars=0: Only displays with at least xxx stars
1186
+     -t, --trusted=false: Only show trusted builds
1187 1187
 
1188 1188
 .. _cli_start:
1189 1189
 
... ...
@@ -1196,8 +1197,8 @@ This example shows 5 containers that might be set up to test a web application c
1196 1196
 
1197 1197
     Start a stopped container
1198 1198
 
1199
-      -a=false: Attach container's stdout/stderr and forward all signals to the process
1200
-      -i=false: Attach container's stdin
1199
+      -a, --attach=false: Attach container's stdout/stderr and forward all signals to the process
1200
+      -i, --interactive=false: Attach container's stdin
1201 1201
 
1202 1202
 .. _cli_stop:
1203 1203
 
... ...
@@ -1210,7 +1211,7 @@ This example shows 5 containers that might be set up to test a web application c
1210 1210
 
1211 1211
     Stop a running container (Send SIGTERM, and then SIGKILL after grace period)
1212 1212
 
1213
-      -t=10: Number of seconds to wait for the container to stop before killing it.
1213
+      -t, --time=10: Number of seconds to wait for the container to stop before killing it.
1214 1214
 
1215 1215
 The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL
1216 1216
 
... ...
@@ -1225,7 +1226,7 @@ The main process inside the container will receive SIGTERM, and after a grace pe
1225 1225
 
1226 1226
     Tag an image into a repository
1227 1227
 
1228
-      -f=false: Force
1228
+      -f, --force=false: Force
1229 1229
 
1230 1230
 .. _cli_top:
1231 1231
 
1232 1232
new file mode 100644
... ...
@@ -0,0 +1,27 @@
0
+Copyright (c) 2014 The Docker & Go Authors. All rights reserved.
1
+
2
+Redistribution and use in source and binary forms, with or without
3
+modification, are permitted provided that the following conditions are
4
+met:
5
+
6
+   * Redistributions of source code must retain the above copyright
7
+notice, this list of conditions and the following disclaimer.
8
+   * Redistributions in binary form must reproduce the above
9
+copyright notice, this list of conditions and the following disclaimer
10
+in the documentation and/or other materials provided with the
11
+distribution.
12
+   * Neither the name of Google Inc. nor the names of its
13
+contributors may be used to endorse or promote products derived from
14
+this software without specific prior written permission.
15
+
16
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 27
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+Package mflag (aka multiple-flag) implements command-line flag parsing.  
1
+It's an **hacky** fork of the [official golang package](http://golang.org/pkg/flag/)
2
+
3
+It adds:
4
+
5
+* both short and long flag version  
6
+`./example -s red` `./example --string blue`
7
+
8
+* multiple names for the same option  
9
+```
10
+$>./example -h
11
+Usage of example:
12
+  -s, --string="": a simple string
13
+```
14
+
15
+___
16
+It is very flexible on purpose, so you can do things like:  
17
+```
18
+$>./example -h
19
+Usage of example:
20
+  -s, -string, --string="": a simple string
21
+```
22
+
23
+Or:  
24
+```
25
+$>./example -h
26
+Usage of example:
27
+  -oldflag, --newflag="": a simple string
28
+```
29
+
30
+You can also hide some flags from the usage, so if we want only `--newflag`:  
31
+```
32
+$>./example -h
33
+Usage of example:
34
+  --newflag="": a simple string
35
+$>./example -oldflag str
36
+str
37
+```
38
+
39
+See [example.go](example/example.go) for more details.
0 40
new file mode 100644
... ...
@@ -0,0 +1,27 @@
0
+package main
1
+
2
+import (
3
+	"fmt"
4
+	"github.com/dotcloud/docker/pkg/flag"
5
+)
6
+
7
+var (
8
+	i    int
9
+	str  string
10
+	b, h bool
11
+)
12
+
13
+func init() {
14
+	flag.BoolVar(&b, []string{"b"}, false, "a simple bool")
15
+	flag.IntVar(&i, []string{"#integer", "-integer"}, -1, "a simple integer")
16
+	flag.StringVar(&str, []string{"s", "#hidden", "-string"}, "", "a simple string") //-s -hidden and --string will work, but -hidden won't be in the usage
17
+	flag.BoolVar(&h, []string{"h", "#help", "-help"}, false, "display the help")
18
+	flag.Parse()
19
+}
20
+func main() {
21
+	if h {
22
+		flag.PrintDefaults()
23
+	}
24
+	fmt.Printf("%s\n", str)
25
+	fmt.Printf("%s\n", flag.Lookup("s").Value.String())
26
+}
0 27
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+// Copyright 2014 The Docker & Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package mflag
5
+
6
+import "os"
7
+
8
+// Additional routines compiled into the package only during testing.
9
+
10
+// ResetForTesting clears all flag state and sets the usage function as directed.
11
+// After calling ResetForTesting, parse errors in flag handling will not
12
+// exit the program.
13
+func ResetForTesting(usage func()) {
14
+	CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
15
+	Usage = usage
16
+}
0 17
new file mode 100644
... ...
@@ -0,0 +1,863 @@
0
+// Copyright 2014 The Docker & Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+/*
5
+	Package flag 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"
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
+	After all flags are defined, call
26
+		flag.Parse()
27
+	to parse the command line into the defined flags.
28
+
29
+	Flags may then be used directly. If you're using the flags themselves,
30
+	they are all pointers; if you bind to variables, they're values.
31
+		fmt.Println("ip has value ", *ip)
32
+		fmt.Println("flagvar has value ", flagvar)
33
+
34
+	After parsing, the arguments after the flag are available as the
35
+	slice flag.Args() or individually as flag.Arg(i).
36
+	The arguments are indexed from 0 through flag.NArg()-1.
37
+
38
+	Command line flag syntax:
39
+		-flag
40
+		-flag=x
41
+		-flag x  // non-boolean flags only
42
+	One or two minus signs may be used; they are equivalent.
43
+	The last form is not permitted for boolean flags because the
44
+	meaning of the command
45
+		cmd -x *
46
+	will change if there is a file called 0, false, etc.  You must
47
+	use the -flag=false form to turn off a boolean flag.
48
+
49
+	Flag parsing stops just before the first non-flag argument
50
+	("-" is a non-flag argument) or after the terminator "--".
51
+
52
+	Integer flags accept 1234, 0664, 0x1234 and may be negative.
53
+	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
54
+	Duration flags accept any input valid for time.ParseDuration.
55
+
56
+	The default set of command-line flags is controlled by
57
+	top-level functions.  The FlagSet type allows one to define
58
+	independent sets of flags, such as to implement subcommands
59
+	in a command-line interface. The methods of FlagSet are
60
+	analogous to the top-level functions for the command-line
61
+	flag set.
62
+*/
63
+package mflag
64
+
65
+import (
66
+	"errors"
67
+	"fmt"
68
+	"io"
69
+	"os"
70
+	"sort"
71
+	"strconv"
72
+	"strings"
73
+	"time"
74
+)
75
+
76
+// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
77
+var ErrHelp = errors.New("flag: help requested")
78
+
79
+// -- bool Value
80
+type boolValue bool
81
+
82
+func newBoolValue(val bool, p *bool) *boolValue {
83
+	*p = val
84
+	return (*boolValue)(p)
85
+}
86
+
87
+func (b *boolValue) Set(s string) error {
88
+	v, err := strconv.ParseBool(s)
89
+	*b = boolValue(v)
90
+	return err
91
+}
92
+
93
+func (b *boolValue) Get() interface{} { return bool(*b) }
94
+
95
+func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
96
+
97
+func (b *boolValue) IsBoolFlag() bool { return true }
98
+
99
+// optional interface to indicate boolean flags that can be
100
+// supplied without "=value" text
101
+type boolFlag interface {
102
+	Value
103
+	IsBoolFlag() bool
104
+}
105
+
106
+// -- int Value
107
+type intValue int
108
+
109
+func newIntValue(val int, p *int) *intValue {
110
+	*p = val
111
+	return (*intValue)(p)
112
+}
113
+
114
+func (i *intValue) Set(s string) error {
115
+	v, err := strconv.ParseInt(s, 0, 64)
116
+	*i = intValue(v)
117
+	return err
118
+}
119
+
120
+func (i *intValue) Get() interface{} { return int(*i) }
121
+
122
+func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
123
+
124
+// -- int64 Value
125
+type int64Value int64
126
+
127
+func newInt64Value(val int64, p *int64) *int64Value {
128
+	*p = val
129
+	return (*int64Value)(p)
130
+}
131
+
132
+func (i *int64Value) Set(s string) error {
133
+	v, err := strconv.ParseInt(s, 0, 64)
134
+	*i = int64Value(v)
135
+	return err
136
+}
137
+
138
+func (i *int64Value) Get() interface{} { return int64(*i) }
139
+
140
+func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
141
+
142
+// -- uint Value
143
+type uintValue uint
144
+
145
+func newUintValue(val uint, p *uint) *uintValue {
146
+	*p = val
147
+	return (*uintValue)(p)
148
+}
149
+
150
+func (i *uintValue) Set(s string) error {
151
+	v, err := strconv.ParseUint(s, 0, 64)
152
+	*i = uintValue(v)
153
+	return err
154
+}
155
+
156
+func (i *uintValue) Get() interface{} { return uint(*i) }
157
+
158
+func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
159
+
160
+// -- uint64 Value
161
+type uint64Value uint64
162
+
163
+func newUint64Value(val uint64, p *uint64) *uint64Value {
164
+	*p = val
165
+	return (*uint64Value)(p)
166
+}
167
+
168
+func (i *uint64Value) Set(s string) error {
169
+	v, err := strconv.ParseUint(s, 0, 64)
170
+	*i = uint64Value(v)
171
+	return err
172
+}
173
+
174
+func (i *uint64Value) Get() interface{} { return uint64(*i) }
175
+
176
+func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
177
+
178
+// -- string Value
179
+type stringValue string
180
+
181
+func newStringValue(val string, p *string) *stringValue {
182
+	*p = val
183
+	return (*stringValue)(p)
184
+}
185
+
186
+func (s *stringValue) Set(val string) error {
187
+	*s = stringValue(val)
188
+	return nil
189
+}
190
+
191
+func (s *stringValue) Get() interface{} { return string(*s) }
192
+
193
+func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
194
+
195
+// -- float64 Value
196
+type float64Value float64
197
+
198
+func newFloat64Value(val float64, p *float64) *float64Value {
199
+	*p = val
200
+	return (*float64Value)(p)
201
+}
202
+
203
+func (f *float64Value) Set(s string) error {
204
+	v, err := strconv.ParseFloat(s, 64)
205
+	*f = float64Value(v)
206
+	return err
207
+}
208
+
209
+func (f *float64Value) Get() interface{} { return float64(*f) }
210
+
211
+func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
212
+
213
+// -- time.Duration Value
214
+type durationValue time.Duration
215
+
216
+func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
217
+	*p = val
218
+	return (*durationValue)(p)
219
+}
220
+
221
+func (d *durationValue) Set(s string) error {
222
+	v, err := time.ParseDuration(s)
223
+	*d = durationValue(v)
224
+	return err
225
+}
226
+
227
+func (d *durationValue) Get() interface{} { return time.Duration(*d) }
228
+
229
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
230
+
231
+// Value is the interface to the dynamic value stored in a flag.
232
+// (The default value is represented as a string.)
233
+//
234
+// If a Value has an IsBoolFlag() bool method returning true,
235
+// the command-line parser makes -name equivalent to -name=true
236
+// rather than using the next command-line argument.
237
+type Value interface {
238
+	String() string
239
+	Set(string) error
240
+}
241
+
242
+// Getter is an interface that allows the contents of a Value to be retrieved.
243
+// It wraps the Value interface, rather than being part of it, because it
244
+// appeared after Go 1 and its compatibility rules. All Value types provided
245
+// by this package satisfy the Getter interface.
246
+type Getter interface {
247
+	Value
248
+	Get() interface{}
249
+}
250
+
251
+// ErrorHandling defines how to handle flag parsing errors.
252
+type ErrorHandling int
253
+
254
+const (
255
+	ContinueOnError ErrorHandling = iota
256
+	ExitOnError
257
+	PanicOnError
258
+)
259
+
260
+// A FlagSet represents a set of defined flags.  The zero value of a FlagSet
261
+// has no name and has ContinueOnError error handling.
262
+type FlagSet struct {
263
+	// Usage is the function called when an error occurs while parsing flags.
264
+	// The field is a function (not a method) that may be changed to point to
265
+	// a custom error handler.
266
+	Usage func()
267
+
268
+	name          string
269
+	parsed        bool
270
+	actual        map[string]*Flag
271
+	formal        map[string]*Flag
272
+	args          []string // arguments after flags
273
+	errorHandling ErrorHandling
274
+	output        io.Writer // nil means stderr; use out() accessor
275
+}
276
+
277
+// A Flag represents the state of a flag.
278
+type Flag struct {
279
+	Names    []string // name as it appears on command line
280
+	Usage    string   // help message
281
+	Value    Value    // value as set
282
+	DefValue string   // default value (as text); for usage message
283
+}
284
+
285
+// sortFlags returns the flags as a slice in lexicographical sorted order.
286
+func sortFlags(flags map[string]*Flag) []*Flag {
287
+	var list sort.StringSlice
288
+	for _, f := range flags {
289
+		found := false
290
+		fName := strings.TrimPrefix(strings.TrimPrefix(f.Names[0], "#"), "-")
291
+		for _, name := range list {
292
+			if name == fName {
293
+				found = true
294
+				break
295
+			}
296
+		}
297
+		if !found {
298
+			list = append(list, fName)
299
+		}
300
+	}
301
+	list.Sort()
302
+	result := make([]*Flag, len(list))
303
+	for i, name := range list {
304
+		result[i] = flags[name]
305
+	}
306
+	return result
307
+}
308
+
309
+func (f *FlagSet) out() io.Writer {
310
+	if f.output == nil {
311
+		return os.Stderr
312
+	}
313
+	return f.output
314
+}
315
+
316
+// SetOutput sets the destination for usage and error messages.
317
+// If output is nil, os.Stderr is used.
318
+func (f *FlagSet) SetOutput(output io.Writer) {
319
+	f.output = output
320
+}
321
+
322
+// VisitAll visits the flags in lexicographical order, calling fn for each.
323
+// It visits all flags, even those not set.
324
+func (f *FlagSet) VisitAll(fn func(*Flag)) {
325
+	for _, flag := range sortFlags(f.formal) {
326
+		fn(flag)
327
+	}
328
+}
329
+
330
+// VisitAll visits the command-line flags in lexicographical order, calling
331
+// fn for each.  It visits all flags, even those not set.
332
+func VisitAll(fn func(*Flag)) {
333
+	CommandLine.VisitAll(fn)
334
+}
335
+
336
+// Visit visits the flags in lexicographical order, calling fn for each.
337
+// It visits only those flags that have been set.
338
+func (f *FlagSet) Visit(fn func(*Flag)) {
339
+	for _, flag := range sortFlags(f.actual) {
340
+		fn(flag)
341
+	}
342
+}
343
+
344
+// Visit visits the command-line flags in lexicographical order, calling fn
345
+// for each.  It visits only those flags that have been set.
346
+func Visit(fn func(*Flag)) {
347
+	CommandLine.Visit(fn)
348
+}
349
+
350
+// Lookup returns the Flag structure of the named flag, returning nil if none exists.
351
+func (f *FlagSet) Lookup(name string) *Flag {
352
+	return f.formal[name]
353
+}
354
+
355
+// Lookup returns the Flag structure of the named command-line flag,
356
+// returning nil if none exists.
357
+func Lookup(name string) *Flag {
358
+	return CommandLine.formal[name]
359
+}
360
+
361
+// Set sets the value of the named flag.
362
+func (f *FlagSet) Set(name, value string) error {
363
+	flag, ok := f.formal[name]
364
+	if !ok {
365
+		return fmt.Errorf("no such flag -%v", name)
366
+	}
367
+	err := flag.Value.Set(value)
368
+	if err != nil {
369
+		return err
370
+	}
371
+	if f.actual == nil {
372
+		f.actual = make(map[string]*Flag)
373
+	}
374
+	f.actual[name] = flag
375
+	return nil
376
+}
377
+
378
+// Set sets the value of the named command-line flag.
379
+func Set(name, value string) error {
380
+	return CommandLine.Set(name, value)
381
+}
382
+
383
+// PrintDefaults prints, to standard error unless configured
384
+// otherwise, the default values of all defined flags in the set.
385
+func (f *FlagSet) PrintDefaults() {
386
+	f.VisitAll(func(flag *Flag) {
387
+		format := "  -%s=%s: %s\n"
388
+		if _, ok := flag.Value.(*stringValue); ok {
389
+			// put quotes on the value
390
+			format = "  -%s=%q: %s\n"
391
+		}
392
+		names := []string{}
393
+		for _, name := range flag.Names {
394
+			if name[0] != '#' {
395
+				names = append(names, name)
396
+			}
397
+		}
398
+		fmt.Fprintf(f.out(), format, strings.Join(names, ", -"), flag.DefValue, flag.Usage)
399
+	})
400
+}
401
+
402
+// PrintDefaults prints to standard error the default values of all defined command-line flags.
403
+func PrintDefaults() {
404
+	CommandLine.PrintDefaults()
405
+}
406
+
407
+// defaultUsage is the default function to print a usage message.
408
+func defaultUsage(f *FlagSet) {
409
+	if f.name == "" {
410
+		fmt.Fprintf(f.out(), "Usage:\n")
411
+	} else {
412
+		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
413
+	}
414
+	f.PrintDefaults()
415
+}
416
+
417
+// NOTE: Usage is not just defaultUsage(CommandLine)
418
+// because it serves (via godoc flag Usage) as the example
419
+// for how to write your own usage function.
420
+
421
+// Usage prints to standard error a usage message documenting all defined command-line flags.
422
+// The function is a variable that may be changed to point to a custom function.
423
+var Usage = func() {
424
+	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
425
+	PrintDefaults()
426
+}
427
+
428
+// NFlag returns the number of flags that have been set.
429
+func (f *FlagSet) NFlag() int { return len(f.actual) }
430
+
431
+// NFlag returns the number of command-line flags that have been set.
432
+func NFlag() int { return len(CommandLine.actual) }
433
+
434
+// Arg returns the i'th argument.  Arg(0) is the first remaining argument
435
+// after flags have been processed.
436
+func (f *FlagSet) Arg(i int) string {
437
+	if i < 0 || i >= len(f.args) {
438
+		return ""
439
+	}
440
+	return f.args[i]
441
+}
442
+
443
+// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
444
+// after flags have been processed.
445
+func Arg(i int) string {
446
+	return CommandLine.Arg(i)
447
+}
448
+
449
+// NArg is the number of arguments remaining after flags have been processed.
450
+func (f *FlagSet) NArg() int { return len(f.args) }
451
+
452
+// NArg is the number of arguments remaining after flags have been processed.
453
+func NArg() int { return len(CommandLine.args) }
454
+
455
+// Args returns the non-flag arguments.
456
+func (f *FlagSet) Args() []string { return f.args }
457
+
458
+// Args returns the non-flag command-line arguments.
459
+func Args() []string { return CommandLine.args }
460
+
461
+// BoolVar defines a bool flag with specified name, default value, and usage string.
462
+// The argument p points to a bool variable in which to store the value of the flag.
463
+func (f *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) {
464
+	f.Var(newBoolValue(value, p), names, usage)
465
+}
466
+
467
+// BoolVar defines a bool flag with specified name, default value, and usage string.
468
+// The argument p points to a bool variable in which to store the value of the flag.
469
+func BoolVar(p *bool, names []string, value bool, usage string) {
470
+	CommandLine.Var(newBoolValue(value, p), names, usage)
471
+}
472
+
473
+// Bool defines a bool flag with specified name, default value, and usage string.
474
+// The return value is the address of a bool variable that stores the value of the flag.
475
+func (f *FlagSet) Bool(names []string, value bool, usage string) *bool {
476
+	p := new(bool)
477
+	f.BoolVar(p, names, value, usage)
478
+	return p
479
+}
480
+
481
+// Bool defines a bool flag with specified name, default value, and usage string.
482
+// The return value is the address of a bool variable that stores the value of the flag.
483
+func Bool(names []string, value bool, usage string) *bool {
484
+	return CommandLine.Bool(names, value, usage)
485
+}
486
+
487
+// IntVar defines an int flag with specified name, default value, and usage string.
488
+// The argument p points to an int variable in which to store the value of the flag.
489
+func (f *FlagSet) IntVar(p *int, names []string, value int, usage string) {
490
+	f.Var(newIntValue(value, p), names, usage)
491
+}
492
+
493
+// IntVar defines an int flag with specified name, default value, and usage string.
494
+// The argument p points to an int variable in which to store the value of the flag.
495
+func IntVar(p *int, names []string, value int, usage string) {
496
+	CommandLine.Var(newIntValue(value, p), names, usage)
497
+}
498
+
499
+// Int defines an int flag with specified name, default value, and usage string.
500
+// The return value is the address of an int variable that stores the value of the flag.
501
+func (f *FlagSet) Int(names []string, value int, usage string) *int {
502
+	p := new(int)
503
+	f.IntVar(p, names, value, usage)
504
+	return p
505
+}
506
+
507
+// Int defines an int flag with specified name, default value, and usage string.
508
+// The return value is the address of an int variable that stores the value of the flag.
509
+func Int(names []string, value int, usage string) *int {
510
+	return CommandLine.Int(names, value, usage)
511
+}
512
+
513
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
514
+// The argument p points to an int64 variable in which to store the value of the flag.
515
+func (f *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) {
516
+	f.Var(newInt64Value(value, p), names, usage)
517
+}
518
+
519
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
520
+// The argument p points to an int64 variable in which to store the value of the flag.
521
+func Int64Var(p *int64, names []string, value int64, usage string) {
522
+	CommandLine.Var(newInt64Value(value, p), names, usage)
523
+}
524
+
525
+// Int64 defines an int64 flag with specified name, default value, and usage string.
526
+// The return value is the address of an int64 variable that stores the value of the flag.
527
+func (f *FlagSet) Int64(names []string, value int64, usage string) *int64 {
528
+	p := new(int64)
529
+	f.Int64Var(p, names, value, usage)
530
+	return p
531
+}
532
+
533
+// Int64 defines an int64 flag with specified name, default value, and usage string.
534
+// The return value is the address of an int64 variable that stores the value of the flag.
535
+func Int64(names []string, value int64, usage string) *int64 {
536
+	return CommandLine.Int64(names, value, usage)
537
+}
538
+
539
+// UintVar defines a uint flag with specified name, default value, and usage string.
540
+// The argument p points to a uint variable in which to store the value of the flag.
541
+func (f *FlagSet) UintVar(p *uint, names []string, value uint, usage string) {
542
+	f.Var(newUintValue(value, p), names, usage)
543
+}
544
+
545
+// UintVar defines a uint flag with specified name, default value, and usage string.
546
+// The argument p points to a uint  variable in which to store the value of the flag.
547
+func UintVar(p *uint, names []string, value uint, usage string) {
548
+	CommandLine.Var(newUintValue(value, p), names, usage)
549
+}
550
+
551
+// Uint defines a uint flag with specified name, default value, and usage string.
552
+// The return value is the address of a uint  variable that stores the value of the flag.
553
+func (f *FlagSet) Uint(names []string, value uint, usage string) *uint {
554
+	p := new(uint)
555
+	f.UintVar(p, names, value, usage)
556
+	return p
557
+}
558
+
559
+// Uint defines a uint flag with specified name, default value, and usage string.
560
+// The return value is the address of a uint  variable that stores the value of the flag.
561
+func Uint(names []string, value uint, usage string) *uint {
562
+	return CommandLine.Uint(names, value, usage)
563
+}
564
+
565
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
566
+// The argument p points to a uint64 variable in which to store the value of the flag.
567
+func (f *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) {
568
+	f.Var(newUint64Value(value, p), names, usage)
569
+}
570
+
571
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
572
+// The argument p points to a uint64 variable in which to store the value of the flag.
573
+func Uint64Var(p *uint64, names []string, value uint64, usage string) {
574
+	CommandLine.Var(newUint64Value(value, p), names, usage)
575
+}
576
+
577
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
578
+// The return value is the address of a uint64 variable that stores the value of the flag.
579
+func (f *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 {
580
+	p := new(uint64)
581
+	f.Uint64Var(p, names, value, usage)
582
+	return p
583
+}
584
+
585
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
586
+// The return value is the address of a uint64 variable that stores the value of the flag.
587
+func Uint64(names []string, value uint64, usage string) *uint64 {
588
+	return CommandLine.Uint64(names, value, usage)
589
+}
590
+
591
+// StringVar defines a string flag with specified name, default value, and usage string.
592
+// The argument p points to a string variable in which to store the value of the flag.
593
+func (f *FlagSet) StringVar(p *string, names []string, value string, usage string) {
594
+	f.Var(newStringValue(value, p), names, usage)
595
+}
596
+
597
+// StringVar defines a string flag with specified name, default value, and usage string.
598
+// The argument p points to a string variable in which to store the value of the flag.
599
+func StringVar(p *string, names []string, value string, usage string) {
600
+	CommandLine.Var(newStringValue(value, p), names, usage)
601
+}
602
+
603
+// String defines a string flag with specified name, default value, and usage string.
604
+// The return value is the address of a string variable that stores the value of the flag.
605
+func (f *FlagSet) String(names []string, value string, usage string) *string {
606
+	p := new(string)
607
+	f.StringVar(p, names, value, usage)
608
+	return p
609
+}
610
+
611
+// String defines a string flag with specified name, default value, and usage string.
612
+// The return value is the address of a string variable that stores the value of the flag.
613
+func String(names []string, value string, usage string) *string {
614
+	return CommandLine.String(names, value, usage)
615
+}
616
+
617
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
618
+// The argument p points to a float64 variable in which to store the value of the flag.
619
+func (f *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) {
620
+	f.Var(newFloat64Value(value, p), names, usage)
621
+}
622
+
623
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
624
+// The argument p points to a float64 variable in which to store the value of the flag.
625
+func Float64Var(p *float64, names []string, value float64, usage string) {
626
+	CommandLine.Var(newFloat64Value(value, p), names, usage)
627
+}
628
+
629
+// Float64 defines a float64 flag with specified name, default value, and usage string.
630
+// The return value is the address of a float64 variable that stores the value of the flag.
631
+func (f *FlagSet) Float64(names []string, value float64, usage string) *float64 {
632
+	p := new(float64)
633
+	f.Float64Var(p, names, value, usage)
634
+	return p
635
+}
636
+
637
+// Float64 defines a float64 flag with specified name, default value, and usage string.
638
+// The return value is the address of a float64 variable that stores the value of the flag.
639
+func Float64(names []string, value float64, usage string) *float64 {
640
+	return CommandLine.Float64(names, value, usage)
641
+}
642
+
643
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
644
+// The argument p points to a time.Duration variable in which to store the value of the flag.
645
+func (f *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
646
+	f.Var(newDurationValue(value, p), names, usage)
647
+}
648
+
649
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
650
+// The argument p points to a time.Duration variable in which to store the value of the flag.
651
+func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
652
+	CommandLine.Var(newDurationValue(value, p), names, usage)
653
+}
654
+
655
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
656
+// The return value is the address of a time.Duration variable that stores the value of the flag.
657
+func (f *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration {
658
+	p := new(time.Duration)
659
+	f.DurationVar(p, names, value, usage)
660
+	return p
661
+}
662
+
663
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
664
+// The return value is the address of a time.Duration variable that stores the value of the flag.
665
+func Duration(names []string, value time.Duration, usage string) *time.Duration {
666
+	return CommandLine.Duration(names, value, usage)
667
+}
668
+
669
+// Var defines a flag with the specified name and usage string. The type and
670
+// value of the flag are represented by the first argument, of type Value, which
671
+// typically holds a user-defined implementation of Value. For instance, the
672
+// caller could create a flag that turns a comma-separated string into a slice
673
+// of strings by giving the slice the methods of Value; in particular, Set would
674
+// decompose the comma-separated string into the slice.
675
+func (f *FlagSet) Var(value Value, names []string, usage string) {
676
+	// Remember the default value as a string; it won't change.
677
+	flag := &Flag{names, usage, value, value.String()}
678
+	for _, name := range names {
679
+		name = strings.TrimPrefix(name, "#")
680
+		_, alreadythere := f.formal[name]
681
+		if alreadythere {
682
+			var msg string
683
+			if f.name == "" {
684
+				msg = fmt.Sprintf("flag redefined: %s", name)
685
+			} else {
686
+				msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
687
+			}
688
+			fmt.Fprintln(f.out(), msg)
689
+			panic(msg) // Happens only if flags are declared with identical names
690
+		}
691
+		if f.formal == nil {
692
+			f.formal = make(map[string]*Flag)
693
+		}
694
+		f.formal[name] = flag
695
+	}
696
+}
697
+
698
+// Var defines a flag with the specified name and usage string. The type and
699
+// value of the flag are represented by the first argument, of type Value, which
700
+// typically holds a user-defined implementation of Value. For instance, the
701
+// caller could create a flag that turns a comma-separated string into a slice
702
+// of strings by giving the slice the methods of Value; in particular, Set would
703
+// decompose the comma-separated string into the slice.
704
+func Var(value Value, names []string, usage string) {
705
+	CommandLine.Var(value, names, usage)
706
+}
707
+
708
+// failf prints to standard error a formatted error and usage message and
709
+// returns the error.
710
+func (f *FlagSet) failf(format string, a ...interface{}) error {
711
+	err := fmt.Errorf(format, a...)
712
+	fmt.Fprintln(f.out(), err)
713
+	f.usage()
714
+	return err
715
+}
716
+
717
+// usage calls the Usage method for the flag set, or the usage function if
718
+// the flag set is CommandLine.
719
+func (f *FlagSet) usage() {
720
+	if f == CommandLine {
721
+		Usage()
722
+	} else if f.Usage == nil {
723
+		defaultUsage(f)
724
+	} else {
725
+		f.Usage()
726
+	}
727
+}
728
+
729
+// parseOne parses one flag. It reports whether a flag was seen.
730
+func (f *FlagSet) parseOne() (bool, error) {
731
+	if len(f.args) == 0 {
732
+		return false, nil
733
+	}
734
+	s := f.args[0]
735
+	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
736
+		return false, nil
737
+	}
738
+	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
739
+		f.args = f.args[1:]
740
+		return false, nil
741
+	}
742
+	name := s[1:]
743
+	if len(name) == 0 || name[0] == '=' {
744
+		return false, f.failf("bad flag syntax: %s", s)
745
+	}
746
+
747
+	// it's a flag. does it have an argument?
748
+	f.args = f.args[1:]
749
+	has_value := false
750
+	value := ""
751
+	for i := 1; i < len(name); i++ { // equals cannot be first
752
+		if name[i] == '=' {
753
+			value = name[i+1:]
754
+			has_value = true
755
+			name = name[0:i]
756
+			break
757
+		}
758
+	}
759
+	m := f.formal
760
+	flag, alreadythere := m[name] // BUG
761
+	if !alreadythere {
762
+		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
763
+			f.usage()
764
+			return false, ErrHelp
765
+		}
766
+		return false, f.failf("flag provided but not defined: -%s", name)
767
+	}
768
+	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
769
+		if has_value {
770
+			if err := fv.Set(value); err != nil {
771
+				return false, f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
772
+			}
773
+		} else {
774
+			fv.Set("true")
775
+		}
776
+	} else {
777
+		// It must have a value, which might be the next argument.
778
+		if !has_value && len(f.args) > 0 {
779
+			// value is the next arg
780
+			has_value = true
781
+			value, f.args = f.args[0], f.args[1:]
782
+		}
783
+		if !has_value {
784
+			return false, f.failf("flag needs an argument: -%s", name)
785
+		}
786
+		if err := flag.Value.Set(value); err != nil {
787
+			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
788
+		}
789
+	}
790
+	if f.actual == nil {
791
+		f.actual = make(map[string]*Flag)
792
+	}
793
+	f.actual[name] = flag
794
+	return true, nil
795
+}
796
+
797
+// Parse parses flag definitions from the argument list, which should not
798
+// include the command name.  Must be called after all flags in the FlagSet
799
+// are defined and before flags are accessed by the program.
800
+// The return value will be ErrHelp if -help was set but not defined.
801
+func (f *FlagSet) Parse(arguments []string) error {
802
+	f.parsed = true
803
+	f.args = arguments
804
+	for {
805
+		seen, err := f.parseOne()
806
+		if seen {
807
+			continue
808
+		}
809
+		if err == nil {
810
+			break
811
+		}
812
+		switch f.errorHandling {
813
+		case ContinueOnError:
814
+			return err
815
+		case ExitOnError:
816
+			os.Exit(2)
817
+		case PanicOnError:
818
+			panic(err)
819
+		}
820
+	}
821
+	return nil
822
+}
823
+
824
+// Parsed reports whether f.Parse has been called.
825
+func (f *FlagSet) Parsed() bool {
826
+	return f.parsed
827
+}
828
+
829
+// Parse parses the command-line flags from os.Args[1:].  Must be called
830
+// after all flags are defined and before flags are accessed by the program.
831
+func Parse() {
832
+	// Ignore errors; CommandLine is set for ExitOnError.
833
+	CommandLine.Parse(os.Args[1:])
834
+}
835
+
836
+// Parsed returns true if the command-line flags have been parsed.
837
+func Parsed() bool {
838
+	return CommandLine.Parsed()
839
+}
840
+
841
+// CommandLine is the default set of command-line flags, parsed from os.Args.
842
+// The top-level functions such as BoolVar, Arg, and on are wrappers for the
843
+// methods of CommandLine.
844
+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
845
+
846
+// NewFlagSet returns a new, empty flag set with the specified name and
847
+// error handling property.
848
+func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
849
+	f := &FlagSet{
850
+		name:          name,
851
+		errorHandling: errorHandling,
852
+	}
853
+	return f
854
+}
855
+
856
+// Init sets the name and error handling property for a flag set.
857
+// By default, the zero FlagSet uses an empty name and the
858
+// ContinueOnError error handling policy.
859
+func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
860
+	f.name = name
861
+	f.errorHandling = errorHandling
862
+}
0 863
new file mode 100644
... ...
@@ -0,0 +1,377 @@
0
+// Copyright 2014 The Docker & Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package mflag_test
5
+
6
+import (
7
+	"bytes"
8
+	"fmt"
9
+	. "github.com/dotcloud/docker/pkg/mflag"
10
+	"os"
11
+	"sort"
12
+	"strings"
13
+	"testing"
14
+	"time"
15
+)
16
+
17
+func boolString(s string) string {
18
+	if s == "0" {
19
+		return "false"
20
+	}
21
+	return "true"
22
+}
23
+
24
+func TestEverything(t *testing.T) {
25
+	ResetForTesting(nil)
26
+	Bool([]string{"test_bool"}, false, "bool value")
27
+	Int([]string{"test_int"}, 0, "int value")
28
+	Int64([]string{"test_int64"}, 0, "int64 value")
29
+	Uint([]string{"test_uint"}, 0, "uint value")
30
+	Uint64([]string{"test_uint64"}, 0, "uint64 value")
31
+	String([]string{"test_string"}, "0", "string value")
32
+	Float64([]string{"test_float64"}, 0, "float64 value")
33
+	Duration([]string{"test_duration"}, 0, "time.Duration value")
34
+
35
+	m := make(map[string]*Flag)
36
+	desired := "0"
37
+	visitor := func(f *Flag) {
38
+		for _, name := range f.Names {
39
+			if len(name) > 5 && name[0:5] == "test_" {
40
+				m[name] = f
41
+				ok := false
42
+				switch {
43
+				case f.Value.String() == desired:
44
+					ok = true
45
+				case name == "test_bool" && f.Value.String() == boolString(desired):
46
+					ok = true
47
+				case name == "test_duration" && f.Value.String() == desired+"s":
48
+					ok = true
49
+				}
50
+				if !ok {
51
+					t.Error("Visit: bad value", f.Value.String(), "for", name)
52
+				}
53
+			}
54
+		}
55
+	}
56
+	VisitAll(visitor)
57
+	if len(m) != 8 {
58
+		t.Error("VisitAll misses some flags")
59
+		for k, v := range m {
60
+			t.Log(k, *v)
61
+		}
62
+	}
63
+	m = make(map[string]*Flag)
64
+	Visit(visitor)
65
+	if len(m) != 0 {
66
+		t.Errorf("Visit sees unset flags")
67
+		for k, v := range m {
68
+			t.Log(k, *v)
69
+		}
70
+	}
71
+	// Now set all flags
72
+	Set("test_bool", "true")
73
+	Set("test_int", "1")
74
+	Set("test_int64", "1")
75
+	Set("test_uint", "1")
76
+	Set("test_uint64", "1")
77
+	Set("test_string", "1")
78
+	Set("test_float64", "1")
79
+	Set("test_duration", "1s")
80
+	desired = "1"
81
+	Visit(visitor)
82
+	if len(m) != 8 {
83
+		t.Error("Visit fails after set")
84
+		for k, v := range m {
85
+			t.Log(k, *v)
86
+		}
87
+	}
88
+	// Now test they're visited in sort order.
89
+	var flagNames []string
90
+	Visit(func(f *Flag) {
91
+		for _, name := range f.Names {
92
+			flagNames = append(flagNames, name)
93
+		}
94
+	})
95
+	if !sort.StringsAreSorted(flagNames) {
96
+		t.Errorf("flag names not sorted: %v", flagNames)
97
+	}
98
+}
99
+
100
+func TestGet(t *testing.T) {
101
+	ResetForTesting(nil)
102
+	Bool([]string{"test_bool"}, true, "bool value")
103
+	Int([]string{"test_int"}, 1, "int value")
104
+	Int64([]string{"test_int64"}, 2, "int64 value")
105
+	Uint([]string{"test_uint"}, 3, "uint value")
106
+	Uint64([]string{"test_uint64"}, 4, "uint64 value")
107
+	String([]string{"test_string"}, "5", "string value")
108
+	Float64([]string{"test_float64"}, 6, "float64 value")
109
+	Duration([]string{"test_duration"}, 7, "time.Duration value")
110
+
111
+	visitor := func(f *Flag) {
112
+		for _, name := range f.Names {
113
+			if len(name) > 5 && name[0:5] == "test_" {
114
+				g, ok := f.Value.(Getter)
115
+				if !ok {
116
+					t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
117
+					return
118
+				}
119
+				switch name {
120
+				case "test_bool":
121
+					ok = g.Get() == true
122
+				case "test_int":
123
+					ok = g.Get() == int(1)
124
+				case "test_int64":
125
+					ok = g.Get() == int64(2)
126
+				case "test_uint":
127
+					ok = g.Get() == uint(3)
128
+				case "test_uint64":
129
+					ok = g.Get() == uint64(4)
130
+				case "test_string":
131
+					ok = g.Get() == "5"
132
+				case "test_float64":
133
+					ok = g.Get() == float64(6)
134
+				case "test_duration":
135
+					ok = g.Get() == time.Duration(7)
136
+				}
137
+				if !ok {
138
+					t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), name)
139
+				}
140
+			}
141
+		}
142
+	}
143
+	VisitAll(visitor)
144
+}
145
+
146
+func TestUsage(t *testing.T) {
147
+	called := false
148
+	ResetForTesting(func() { called = true })
149
+	if CommandLine.Parse([]string{"-x"}) == nil {
150
+		t.Error("parse did not fail for unknown flag")
151
+	}
152
+	if !called {
153
+		t.Error("did not call Usage for unknown flag")
154
+	}
155
+}
156
+
157
+func testParse(f *FlagSet, t *testing.T) {
158
+	if f.Parsed() {
159
+		t.Error("f.Parse() = true before Parse")
160
+	}
161
+	boolFlag := f.Bool([]string{"bool"}, false, "bool value")
162
+	bool2Flag := f.Bool([]string{"bool2"}, false, "bool2 value")
163
+	intFlag := f.Int([]string{"-int"}, 0, "int value")
164
+	int64Flag := f.Int64([]string{"-int64"}, 0, "int64 value")
165
+	uintFlag := f.Uint([]string{"uint"}, 0, "uint value")
166
+	uint64Flag := f.Uint64([]string{"-uint64"}, 0, "uint64 value")
167
+	stringFlag := f.String([]string{"string"}, "0", "string value")
168
+	float64Flag := f.Float64([]string{"float64"}, 0, "float64 value")
169
+	durationFlag := f.Duration([]string{"duration"}, 5*time.Second, "time.Duration value")
170
+	extra := "one-extra-argument"
171
+	args := []string{
172
+		"-bool",
173
+		"-bool2=true",
174
+		"--int", "22",
175
+		"--int64", "0x23",
176
+		"-uint", "24",
177
+		"--uint64", "25",
178
+		"-string", "hello",
179
+		"-float64", "2718e28",
180
+		"-duration", "2m",
181
+		extra,
182
+	}
183
+	if err := f.Parse(args); err != nil {
184
+		t.Fatal(err)
185
+	}
186
+	if !f.Parsed() {
187
+		t.Error("f.Parse() = false after Parse")
188
+	}
189
+	if *boolFlag != true {
190
+		t.Error("bool flag should be true, is ", *boolFlag)
191
+	}
192
+	if *bool2Flag != true {
193
+		t.Error("bool2 flag should be true, is ", *bool2Flag)
194
+	}
195
+	if *intFlag != 22 {
196
+		t.Error("int flag should be 22, is ", *intFlag)
197
+	}
198
+	if *int64Flag != 0x23 {
199
+		t.Error("int64 flag should be 0x23, is ", *int64Flag)
200
+	}
201
+	if *uintFlag != 24 {
202
+		t.Error("uint flag should be 24, is ", *uintFlag)
203
+	}
204
+	if *uint64Flag != 25 {
205
+		t.Error("uint64 flag should be 25, is ", *uint64Flag)
206
+	}
207
+	if *stringFlag != "hello" {
208
+		t.Error("string flag should be `hello`, is ", *stringFlag)
209
+	}
210
+	if *float64Flag != 2718e28 {
211
+		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
212
+	}
213
+	if *durationFlag != 2*time.Minute {
214
+		t.Error("duration flag should be 2m, is ", *durationFlag)
215
+	}
216
+	if len(f.Args()) != 1 {
217
+		t.Error("expected one argument, got", len(f.Args()))
218
+	} else if f.Args()[0] != extra {
219
+		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
220
+	}
221
+}
222
+
223
+func TestParse(t *testing.T) {
224
+	ResetForTesting(func() { t.Error("bad parse") })
225
+	testParse(CommandLine, t)
226
+}
227
+
228
+func TestFlagSetParse(t *testing.T) {
229
+	testParse(NewFlagSet("test", ContinueOnError), t)
230
+}
231
+
232
+// Declare a user-defined flag type.
233
+type flagVar []string
234
+
235
+func (f *flagVar) String() string {
236
+	return fmt.Sprint([]string(*f))
237
+}
238
+
239
+func (f *flagVar) Set(value string) error {
240
+	*f = append(*f, value)
241
+	return nil
242
+}
243
+
244
+func TestUserDefined(t *testing.T) {
245
+	var flags FlagSet
246
+	flags.Init("test", ContinueOnError)
247
+	var v flagVar
248
+	flags.Var(&v, []string{"v"}, "usage")
249
+	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
250
+		t.Error(err)
251
+	}
252
+	if len(v) != 3 {
253
+		t.Fatal("expected 3 args; got ", len(v))
254
+	}
255
+	expect := "[1 2 3]"
256
+	if v.String() != expect {
257
+		t.Errorf("expected value %q got %q", expect, v.String())
258
+	}
259
+}
260
+
261
+// Declare a user-defined boolean flag type.
262
+type boolFlagVar struct {
263
+	count int
264
+}
265
+
266
+func (b *boolFlagVar) String() string {
267
+	return fmt.Sprintf("%d", b.count)
268
+}
269
+
270
+func (b *boolFlagVar) Set(value string) error {
271
+	if value == "true" {
272
+		b.count++
273
+	}
274
+	return nil
275
+}
276
+
277
+func (b *boolFlagVar) IsBoolFlag() bool {
278
+	return b.count < 4
279
+}
280
+
281
+func TestUserDefinedBool(t *testing.T) {
282
+	var flags FlagSet
283
+	flags.Init("test", ContinueOnError)
284
+	var b boolFlagVar
285
+	var err error
286
+	flags.Var(&b, []string{"b"}, "usage")
287
+	if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
288
+		if b.count < 4 {
289
+			t.Error(err)
290
+		}
291
+	}
292
+
293
+	if b.count != 4 {
294
+		t.Errorf("want: %d; got: %d", 4, b.count)
295
+	}
296
+
297
+	if err == nil {
298
+		t.Error("expected error; got none")
299
+	}
300
+}
301
+
302
+func TestSetOutput(t *testing.T) {
303
+	var flags FlagSet
304
+	var buf bytes.Buffer
305
+	flags.SetOutput(&buf)
306
+	flags.Init("test", ContinueOnError)
307
+	flags.Parse([]string{"-unknown"})
308
+	if out := buf.String(); !strings.Contains(out, "-unknown") {
309
+		t.Logf("expected output mentioning unknown; got %q", out)
310
+	}
311
+}
312
+
313
+// This tests that one can reset the flags. This still works but not well, and is
314
+// superseded by FlagSet.
315
+func TestChangingArgs(t *testing.T) {
316
+	ResetForTesting(func() { t.Fatal("bad parse") })
317
+	oldArgs := os.Args
318
+	defer func() { os.Args = oldArgs }()
319
+	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
320
+	before := Bool([]string{"before"}, false, "")
321
+	if err := CommandLine.Parse(os.Args[1:]); err != nil {
322
+		t.Fatal(err)
323
+	}
324
+	cmd := Arg(0)
325
+	os.Args = Args()
326
+	after := Bool([]string{"after"}, false, "")
327
+	Parse()
328
+	args := Args()
329
+
330
+	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
331
+		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
332
+	}
333
+}
334
+
335
+// Test that -help invokes the usage message and returns ErrHelp.
336
+func TestHelp(t *testing.T) {
337
+	var helpCalled = false
338
+	fs := NewFlagSet("help test", ContinueOnError)
339
+	fs.Usage = func() { helpCalled = true }
340
+	var flag bool
341
+	fs.BoolVar(&flag, []string{"flag"}, false, "regular flag")
342
+	// Regular flag invocation should work
343
+	err := fs.Parse([]string{"-flag=true"})
344
+	if err != nil {
345
+		t.Fatal("expected no error; got ", err)
346
+	}
347
+	if !flag {
348
+		t.Error("flag was not set by -flag")
349
+	}
350
+	if helpCalled {
351
+		t.Error("help called for regular flag")
352
+		helpCalled = false // reset for next test
353
+	}
354
+	// Help flag should work as expected.
355
+	err = fs.Parse([]string{"-help"})
356
+	if err == nil {
357
+		t.Fatal("error expected")
358
+	}
359
+	if err != ErrHelp {
360
+		t.Fatal("expected ErrHelp; got ", err)
361
+	}
362
+	if !helpCalled {
363
+		t.Fatal("help was not called")
364
+	}
365
+	// If we define a help flag, that should override.
366
+	var help bool
367
+	fs.BoolVar(&help, []string{"help"}, false, "help flag")
368
+	helpCalled = false
369
+	err = fs.Parse([]string{"-help"})
370
+	if err != nil {
371
+		t.Fatal("expected no error for defined -help; got ", err)
372
+	}
373
+	if helpCalled {
374
+		t.Fatal("help was called; should not have been for defined help flag")
375
+	}
376
+}