Merge pull request #23825 from dnephin/auto-gen-man-page

Generate man pages from the Command description
This commit is contained in:
Arnaud Porterie 2016-07-19 18:22:01 +00:00 committed by GitHub
commit ac26ee15df
22 changed files with 258 additions and 243 deletions

View File

@ -126,6 +126,12 @@ test-unit: build ## run the unit tests
validate: build ## validate DCO, Seccomp profile generation, gofmt,\n./pkg/ isolation, golint, tests, tomls, go vet and vendor
$(DOCKER_RUN_DOCKER) hack/make.sh validate-dco validate-default-seccomp validate-gofmt validate-pkg validate-lint validate-test validate-toml validate-vet validate-vendor
manpages: ## Generate man pages from go source and markdown
docker build -t docker-manpage-dev -f man/Dockerfile .
docker run \
-v $(PWD):/go/src/github.com/docker/docker/ \
docker-manpage-dev
help: ## this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

View File

@ -12,8 +12,9 @@ import (
// NewVolumeCommand returns a cobra command for `volume` subcommands
func NewVolumeCommand(dockerCli *client.DockerCli) *cobra.Command {
cmd := &cobra.Command{
Use: "volume",
Use: "volume COMMAND",
Short: "Manage Docker volumes",
Long: volumeDescription,
Args: cli.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
@ -27,3 +28,21 @@ func NewVolumeCommand(dockerCli *client.DockerCli) *cobra.Command {
)
return cmd
}
var volumeDescription = `
The **docker volume** command has subcommands for managing data volumes. A data
volume is a specially-designated directory that by-passes storage driver
management.
Data volumes persist data independent of a container's life cycle. When you
delete a container, the Engine daemon does not delete any data volumes. You can
share volumes across multiple containers. Moreover, you can share data volumes
with other computing resources in your system.
To see help for a subcommand, use:
docker volume CMD help
For full details on using docker volume visit Docker's online documentation.
`

View File

@ -28,6 +28,7 @@ func newCreateCommand(dockerCli *client.DockerCli) *cobra.Command {
cmd := &cobra.Command{
Use: "create [OPTIONS]",
Short: "Create a volume",
Long: createDescription,
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return runCreate(dockerCli, opts)
@ -60,3 +61,42 @@ func runCreate(dockerCli *client.DockerCli, opts createOptions) error {
fmt.Fprintf(dockerCli.Out(), "%s\n", vol.Name)
return nil
}
var createDescription = `
Creates a new volume that containers can consume and store data in. If a name
is not specified, Docker generates a random name. You create a volume and then
configure the container to use it, for example:
$ docker volume create --name hello
hello
$ docker run -d -v hello:/world busybox ls /world
The mount is created inside the container's **/src** directory. Docker doesn't
not support relative paths for mount points inside the container.
Multiple containers can use the same volume in the same time period. This is
useful if two containers need access to shared data. For example, if one
container writes and the other reads the data.
## Driver specific options
Some volume drivers may take options to customize the volume creation. Use the
**-o** or **--opt** flags to pass driver options:
$ docker volume create --driver fake --opt tardis=blue --opt timey=wimey
These options are passed directly to the volume driver. Options for different
volume drivers may do different things (or nothing at all).
The built-in **local** driver on Windows does not support any options.
The built-in **local** driver on Linux accepts options similar to the linux
**mount** command:
$ docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000
Another example:
$ docker volume create --driver local --opt type=btrfs --opt device=/dev/sda2
`

View File

@ -20,6 +20,7 @@ func newInspectCommand(dockerCli *client.DockerCli) *cobra.Command {
cmd := &cobra.Command{
Use: "inspect [OPTIONS] VOLUME [VOLUME...]",
Short: "Display detailed information on one or more volumes",
Long: inspectDescription,
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.names = args
@ -44,3 +45,11 @@ func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error {
return inspect.Inspect(dockerCli.Out(), opts.names, opts.format, getVolFunc)
}
var inspectDescription = `
Returns information about one or more volumes. By default, this command renders
all results in a JSON array. You can specify an alternate format to execute a
given template is executed for each result. Go's https://golang.org/pkg/text/template/
package describes all the details of the format.
`

View File

@ -34,6 +34,7 @@ func newListCommand(dockerCli *client.DockerCli) *cobra.Command {
Use: "ls [OPTIONS]",
Aliases: []string{"list"},
Short: "List volumes",
Long: listDescription,
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return runList(dockerCli, opts)
@ -84,3 +85,15 @@ func runList(dockerCli *client.DockerCli, opts listOptions) error {
w.Flush()
return nil
}
var listDescription = `
Lists all the volumes Docker knows about. You can filter using the **-f** or
**--filter** flag. The filtering format is a **key=value** pair. To specify
more than one filter, pass multiple flags (for example,
**--filter "foo=bar" --filter "bif=baz"**)
There is a single supported filter **dangling=value** which takes a boolean of
**true** or **false**.
`

View File

@ -15,6 +15,8 @@ func newRemoveCommand(dockerCli *client.DockerCli) *cobra.Command {
Use: "rm VOLUME [VOLUME]...",
Aliases: []string{"remove"},
Short: "Remove a volume",
Long: removeDescription,
Example: removeExample,
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runRemove(dockerCli, args)
@ -41,3 +43,12 @@ func runRemove(dockerCli *client.DockerCli, volumes []string) error {
}
return nil
}
var removeDescription = `
Removes one or more volumes. You cannot remove a volume that is in use by a container.
`
var removeExample = `
$ docker volume rm hello
hello
`

View File

@ -33,6 +33,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
var rootCmd = &cobra.Command{
Use: "docker [OPTIONS]",
Short: "A self-sufficient runtime for containers",
SilenceUsage: true,
SilenceErrors: true,
}
@ -131,9 +132,15 @@ func (c CobraAdaptor) Command(name string) func(...string) error {
return nil
}
// GetRootCommand returns the root command. Required to generate the man pages
// and reference docs from a script outside this package.
func (c CobraAdaptor) GetRootCommand() *cobra.Command {
return c.rootCmd
}
var usageTemplate = `Usage: {{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}}
{{with or .Long .Short }}{{. | trim}}{{end}}{{if gt .Aliases 0}}
{{ .Short | trim }}{{if gt .Aliases 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}

View File

@ -35,7 +35,7 @@ set -e
debDate="$(date --rfc-2822)"
# if go-md2man is available, pre-generate the man pages
./man/md2man-all.sh -q || true
./man/generate.sh || true
# TODO decide if it's worth getting go-md2man in _each_ builder environment to avoid this
builderDir="contrib/builder/deb/${PACKAGE_ARCH}"

View File

@ -51,7 +51,7 @@ set -e
rpmDate="$(date +'%a %b %d %Y')"
# if go-md2man is available, pre-generate the man pages
./man/md2man-all.sh -q || true
./man/generate.sh || true
# TODO decide if it's worth getting go-md2man in _each_ builder environment to avoid this
# Convert the CHANGELOG.md file into RPM changelog format

View File

@ -32,6 +32,7 @@ bundle_test_unit() {
"${BUILDFLAGS[@]}" $TEST_PATH \
| grep github.com/docker/docker \
| grep -v github.com/docker/docker/vendor \
| grep -v github.com/docker/docker/man \
| grep -v github.com/docker/docker/integration-cli)
go test $COVER $GCCGOFLAGS -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS $pkg_list
}

View File

@ -59,8 +59,8 @@ bundle_ubuntu() {
mkdir -p "$DIR/etc/fish/completions"
cp contrib/completion/fish/docker.fish "$DIR/etc/fish/completions/"
# Include contributed man pages
man/md2man-all.sh -q
# Include man pages
man/generate.sh
manRoot="$DIR/usr/share/man"
mkdir -p "$manRoot"
for manDir in man/man?; do

View File

@ -1,7 +1,20 @@
FROM golang:1.6.3
RUN mkdir -p /go/src/github.com/cpuguy83
RUN mkdir -p /go/src/github.com/cpuguy83 \
&& git clone -b v1.0.5 https://github.com/cpuguy83/go-md2man.git /go/src/github.com/cpuguy83/go-md2man \
&& cd /go/src/github.com/cpuguy83/go-md2man \
&& go get -v ./...
CMD ["/go/bin/go-md2man", "--help"]
FROM golang:1.6.3-alpine
RUN apk add -U git bash curl gcc musl-dev
RUN export GLIDE=0.10.2; \
export SRC=https://github.com/Masterminds/glide/releases/download/; \
curl -sL ${SRC}/${GLIDE}/glide-${GLIDE}-linux-amd64.tar.gz | \
tar -xz linux-amd64/glide && \
mv linux-amd64/glide /usr/bin/glide && \
chmod +x /usr/bin/glide
COPY man/glide.yaml /manvendor/
COPY man/glide.lock /manvendor/
WORKDIR /manvendor/
RUN glide install && mv vendor src
ENV GOPATH=$GOPATH:/go/src/github.com/docker/docker/vendor:/manvendor
RUN go build -o /usr/bin/go-md2man github.com/cpuguy83/go-md2man
WORKDIR /go/src/github.com/docker/docker/
ENTRYPOINT ["man/generate.sh"]

View File

@ -1,33 +1,15 @@
Docker Documentation
====================
This directory contains the Docker user manual in the Markdown format.
Do *not* edit the man pages in the man1 directory. Instead, amend the
Markdown (*.md) files.
This directory contains scripts for generating the man pages. Many of the man
pages are generated directly from the `spf13/cobra` `Command` definition. Some
legacy pages are still generated from the markdown files in this directory.
Do *not* edit the man pages in the man1 directory. Instead, update the
Cobra command or amend the Markdown files for legacy pages.
# Generating man pages from the Markdown files
The recommended approach for generating the man pages is via a Docker
container using the supplied `Dockerfile` to create an image with the correct
environment. This uses `go-md2man`, a pure Go Markdown to man page generator.
## Generate the mange pages
## Building the md2man image
From within the project root directory run:
There is a `Dockerfile` provided in the `/man` directory of your
'docker/docker' fork.
Using this `Dockerfile`, create a Docker image tagged `docker/md2man`:
docker build -t docker/md2man .
## Utilizing the image
From within the `/man` directory run the following command:
docker run -v $(pwd):/man -w /man -i docker/md2man ./md2man-all.sh
The `md2man` Docker container will process the Markdown files and generate
the man pages inside the `/man/man1` directory of your fork using
Docker volumes. For more information on Docker volumes see the man page for
`docker run` and also look at the article [Sharing Directories via Volumes]
(https://docs.docker.com/use/working_with_volumes/).
make manpages

View File

@ -1,65 +0,0 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% JULY 2015
# NAME
docker-volume-create - Create a new volume
# SYNOPSIS
**docker volume create**
[**-d**|**--driver**[=*DRIVER*]]
[**--help**]
[**--label**[=*[]*]]
[**--name**[=*NAME*]]
[**-o**|**--opt**[=*[]*]]
# DESCRIPTION
Creates a new volume that containers can consume and store data in. If a name is not specified, Docker generates a random name. You create a volume and then configure the container to use it, for example:
$ docker volume create --name hello
hello
$ docker run -d -v hello:/world busybox ls /world
The mount is created inside the container's `/src` directory. Docker doesn't not support relative paths for mount points inside the container.
Multiple containers can use the same volume in the same time period. This is useful if two containers need access to shared data. For example, if one container writes and the other reads the data.
## Driver specific options
Some volume drivers may take options to customize the volume creation. Use the `-o` or `--opt` flags to pass driver options:
$ docker volume create --driver fake --opt tardis=blue --opt timey=wimey
These options are passed directly to the volume driver. Options for
different volume drivers may do different things (or nothing at all).
The built-in `local` driver on Windows does not support any options.
The built-in `local` driver on Linux accepts options similar to the linux `mount`
command:
$ docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000
Another example:
$ docker volume create --driver local --opt type=btrfs --opt device=/dev/sda2
# OPTIONS
**-d**, **--driver**="*local*"
Specify volume driver name
**--help**
Print usage statement
**--label**=*label*
Set metadata for a volume
**--name**=""
Specify volume name
**-o**, **--opt**=[]
Set driver specific options
# HISTORY
July 2015, created by Brian Goff <cpuguy83@gmail.com>

View File

@ -1,29 +0,0 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% JULY 2015
# NAME
docker-volume-inspect - Get low-level information about a volume
# SYNOPSIS
**docker volume inspect**
[**-f**|**--format**[=*FORMAT*]]
[**--help**]
VOLUME [VOLUME...]
# DESCRIPTION
Returns information about one or more volumes. By default, this command renders all results
in a JSON array. You can specify an alternate format to execute a given template
is executed for each result. Go's
http://golang.org/pkg/text/template/ package describes all the details of the
format.
# OPTIONS
**-f**, **--format**=""
Format the output using the given go template.
**--help**
Print usage statement
# HISTORY
July 2015, created by Brian Goff <cpuguy83@gmail.com>

View File

@ -1,33 +0,0 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% JULY 2015
# NAME
docker-volume-ls - List all volumes
# SYNOPSIS
**docker volume ls**
[**-f**|**--filter**[=*FILTER*]]
[**--help**]
[**-q**|**--quiet**[=*true*|*false*]]
# DESCRIPTION
Lists all the volumes Docker knows about. You can filter using the `-f` or `--filter` flag. The filtering format is a `key=value` pair. To specify more than one filter, pass multiple flags (for example, `--filter "foo=bar" --filter "bif=baz"`)
There is a single supported filter `dangling=value` which takes a boolean of `true` or `false`.
# OPTIONS
**-f**, **--filter**=""
Filter output based on these conditions:
- dangling=<boolean> a volume if referenced or not
- driver=<string> a volume's driver name
- name=<string> a volume's name
**--help**
Print usage statement
**-q**, **--quiet**=*true*|*false*
Only display volume names
# HISTORY
July 2015, created by Brian Goff <cpuguy83@gmail.com>

View File

@ -1,26 +0,0 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% JULY 2015
# NAME
docker-volume-rm - Remove a volume
# SYNOPSIS
**docker volume rm**
[**--help**]
VOLUME [VOLUME...]
# DESCRIPTION
Removes one or more volumes. You cannot remove a volume that is in use by a container.
```
$ docker volume rm hello
hello
```
# OPTIONS
**--help**
Print usage statement
# HISTORY
July 2015, created by Brian Goff <cpuguy83@gmail.com>

View File

@ -1,51 +0,0 @@
% DOCKER(1) Docker User Manuals
% Docker Community
% Feb 2016
# NAME
docker-volume - Create a new volume
# SYNOPSIS
**docker volume** [OPTIONS] COMMAND
[**--help**]
# DESCRIPTION
docker volume has subcommands for managing data volumes.
## Data volumes
The `docker volume` command has subcommands for managing data volumes. A data volume is a specially-designated directory that by-passes storage driver management.
Data volumes persist data independent of a container's life cycle. When you delete a container, the Engine daemon does not delete any data volumes. You can share volumes across multiple containers. Moreover, you can share data volumes with other computing resources in your system.
To see help for a subcommand, use:
```
docker volume CMD help
```
For full details on using docker volume visit Docker's online documentation.
# OPTIONS
**--help**
Print usage statement
# COMMANDS
**create**
Create a volume
See **docker-volume-create(1)** for full documentation on the **create** command.
**inspect**
Display detailed information on one or more volumes
See **docker-volume-inspect(1)** for full documentation on the **inspect** command.
**ls**
List volumes
See **docker-volume-ls(1)** for full documentation on the **ls** command.
**rm**
Remove a volume
See **docker-volume-rm(1)** for full documentation on the **rm** command.
# HISTORY
Feb 2016, created by Dan Walsh <dwalsh@redhat.com>

39
man/generate.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"fmt"
"os"
"github.com/docker/docker/cli/cobraadaptor"
cliflags "github.com/docker/docker/cli/flags"
"github.com/spf13/cobra/doc"
)
func generateManPages(path string) error {
header := &doc.GenManHeader{
Title: "DOCKER",
Section: "1",
Source: "Docker Community",
}
flags := &cliflags.ClientFlags{
Common: cliflags.InitCommonFlags(),
}
cmd := cobraadaptor.NewCobraAdaptor(flags).GetRootCommand()
cmd.DisableAutoGenTag = true
return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{
Header: header,
Path: path,
CommandSeparator: "-",
})
}
func main() {
path := "/tmp"
if len(os.Args) > 1 {
path = os.Args[1]
}
fmt.Printf("Generating man pages into %s\n", path)
if err := generateManPages(path); err != nil {
fmt.Fprintf(os.Stderr, "Failed to generate man pages: %s\n", err.Error())
}
}

15
man/generate.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
#
# Generate man pages for docker/docker
#
set -eu
mkdir -p ./man/man1
# Generate man pages from cobra commands
go build -o /tmp/gen-manpages ./man
/tmp/gen-manpages ./man/man1
# Generate legacy pages from markdown
./man/md2man-all.sh -q

52
man/glide.lock generated Normal file
View File

@ -0,0 +1,52 @@
hash: ead3ea293a6143fe41069ebec814bf197d8c43a92cc7666b1f7e21a419b46feb
updated: 2016-06-20T21:53:35.420817456Z
imports:
- name: github.com/BurntSushi/toml
version: f0aeabca5a127c4078abb8c8d64298b147264b55
- name: github.com/cpuguy83/go-md2man
version: 2724a9c9051aa62e9cca11304e7dd518e9e41599
subpackages:
- md2man
- name: github.com/fsnotify/fsnotify
version: 30411dbcefb7a1da7e84f75530ad3abe4011b4f8
- name: github.com/hashicorp/hcl
version: da486364306ed66c218be9b7953e19173447c18b
subpackages:
- hcl/ast
- hcl/parser
- hcl/token
- json/parser
- hcl/scanner
- hcl/strconv
- json/scanner
- json/token
- name: github.com/inconshreveable/mousetrap
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
- name: github.com/magiconair/properties
version: c265cfa48dda6474e208715ca93e987829f572f8
- name: github.com/mitchellh/mapstructure
version: d2dd0262208475919e1a362f675cfc0e7c10e905
- name: github.com/russross/blackfriday
version: 1d6b8e9301e720b08a8938b8c25c018285885438
- name: github.com/shurcooL/sanitized_anchor_name
version: 10ef21a441db47d8b13ebcc5fd2310f636973c77
- name: github.com/spf13/cast
version: 27b586b42e29bec072fe7379259cc719e1289da6
- name: github.com/spf13/jwalterweatherman
version: 33c24e77fb80341fe7130ee7c594256ff08ccc46
- name: github.com/spf13/pflag
version: 367864438f1b1a3c7db4da06a2f55b144e6784e0
- name: github.com/spf13/viper
version: c1ccc378a054ea8d4e38d8c67f6938d4760b53dd
- name: golang.org/x/sys
version: 62bee037599929a6e9146f29d10dd5208c43507d
subpackages:
- unix
- name: gopkg.in/yaml.v2
version: a83829b6f1293c91addabc89d0571c246397bbf4
- name: github.com/spf13/cobra
repo: https://github.com/dnephin/cobra
subpackages:
- doc
version: v1.3
devImports: []

12
man/glide.yaml Normal file
View File

@ -0,0 +1,12 @@
package: github.com/docker/docker/man
import:
- package: github.com/cpuguy83/go-md2man
subpackages:
- md2man
- package: github.com/inconshreveable/mousetrap
- package: github.com/spf13/pflag
- package: github.com/spf13/viper
- package: github.com/spf13/cobra
repo: https://github.com/dnephin/cobra
subpackages:
- doc