diff --git a/clidocstool.go b/clidocstool.go index d4aeaba..1c67a52 100644 --- a/clidocstool.go +++ b/clidocstool.go @@ -17,10 +17,13 @@ package clidocstool import ( "errors" "io" + "log" "os" + "path/filepath" "strings" "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" ) // Options defines options for cli-docs-tool @@ -29,6 +32,8 @@ type Options struct { SourceDir string TargetDir string Plugin bool + + ManHeader *doc.GenManHeader } // Client represents an active cli-docs-tool object @@ -37,6 +42,8 @@ type Client struct { source string target string plugin bool + + manHeader *doc.GenManHeader } // New initializes a new cli-docs-tool client @@ -48,9 +55,10 @@ func New(opts Options) (*Client, error) { return nil, errors.New("source dir required") } c := &Client{ - root: opts.Root, - source: opts.SourceDir, - plugin: opts.Plugin, + root: opts.Root, + source: opts.SourceDir, + plugin: opts.Plugin, + manHeader: opts.ManHeader, } if len(opts.TargetDir) == 0 { c.target = c.source @@ -73,9 +81,69 @@ func (c *Client) GenAllTree() error { if err = c.GenYamlTree(c.root); err != nil { return err } + if err = c.GenManTree(c.root); err != nil { + return err + } return nil } +// loadLongDescription gets long descriptions and examples from markdown. +func (c *Client) loadLongDescription(parentCmd *cobra.Command, generator string) error { + for _, cmd := range parentCmd.Commands() { + if cmd.HasSubCommands() { + if err := c.loadLongDescription(cmd, generator); err != nil { + return err + } + } + name := cmd.CommandPath() + if i := strings.Index(name, " "); i >= 0 { + // remove root command / binary name + name = name[i+1:] + } + if name == "" { + continue + } + mdFile := strings.ReplaceAll(name, " ", "_") + ".md" + sourcePath := filepath.Join(c.source, mdFile) + content, err := os.ReadFile(sourcePath) + if os.IsNotExist(err) { + log.Printf("WARN: %s does not exist, skipping Markdown examples for %s docs\n", mdFile, generator) + continue + } + if err != nil { + return err + } + applyDescriptionAndExamples(cmd, string(content)) + } + return nil +} + +// applyDescriptionAndExamples fills in cmd.Long and cmd.Example with the +// "Description" and "Examples" H2 sections in mdString (if present). +func applyDescriptionAndExamples(cmd *cobra.Command, mdString string) { + sections := getSections(mdString) + var ( + anchors []string + md string + ) + if sections["description"] != "" { + md, anchors = cleanupMarkDown(sections["description"]) + cmd.Long = md + anchors = append(anchors, md) + } + if sections["examples"] != "" { + md, anchors = cleanupMarkDown(sections["examples"]) + cmd.Example = md + anchors = append(anchors, md) + } + if len(anchors) > 0 { + if cmd.Annotations == nil { + cmd.Annotations = make(map[string]string) + } + cmd.Annotations["anchors"] = strings.Join(anchors, ",") + } +} + func fileExists(f string) bool { info, err := os.Stat(f) if os.IsNotExist(err) { diff --git a/clidocstool_man.go b/clidocstool_man.go new file mode 100644 index 0000000..e043f99 --- /dev/null +++ b/clidocstool_man.go @@ -0,0 +1,74 @@ +// Copyright 2016 cli-docs-tool authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package clidocstool + +import ( + "fmt" + "log" + "os" + "strconv" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +// GenManTree generates a man page for the command and all descendants. +// If SOURCE_DATE_EPOCH is set, in order to allow reproducible package +// builds, we explicitly set the build time to SOURCE_DATE_EPOCH. +func (c *Client) GenManTree(cmd *cobra.Command) error { + if err := c.loadLongDescription(cmd, "man"); err != nil { + return err + } + + if epoch := os.Getenv("SOURCE_DATE_EPOCH"); c.manHeader != nil && epoch != "" { + unixEpoch, err := strconv.ParseInt(epoch, 10, 64) + if err != nil { + return fmt.Errorf("invalid SOURCE_DATE_EPOCH: %v", err) + } + now := time.Unix(unixEpoch, 0) + c.manHeader.Date = &now + } + + return c.genManTreeCustom(cmd) +} + +func (c *Client) genManTreeCustom(cmd *cobra.Command) error { + for _, sc := range cmd.Commands() { + if err := c.genManTreeCustom(sc); err != nil { + return err + } + } + + // always disable the addition of [flags] to the usage + cmd.DisableFlagsInUseLine = true + + // always disable "spf13/cobra" auto gen tag + cmd.DisableAutoGenTag = true + + // Skip the root command altogether, to prevent generating a useless + // md file for plugins. + if c.plugin && !cmd.HasParent() { + return nil + } + + log.Printf("INFO: Generating Man for %q", cmd.CommandPath()) + + return doc.GenManTreeFromOpts(cmd, doc.GenManTreeOptions{ + Header: c.manHeader, + Path: c.target, + CommandSeparator: "-", + }) +} diff --git a/clidocstool_man_test.go b/clidocstool_man_test.go new file mode 100644 index 0000000..336edf7 --- /dev/null +++ b/clidocstool_man_test.go @@ -0,0 +1,93 @@ +// Copyright 2024 cli-docs-tool authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package clidocstool + +import ( + "io/fs" + "os" + "path" + "path/filepath" + "regexp" + "strconv" + "testing" + "time" + + "github.com/spf13/cobra/doc" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +//nolint:errcheck +func TestGenManTree(t *testing.T) { + setup() + tmpdir := t.TempDir() + + epoch, err := time.Parse("2006-Jan-02", "2020-Jan-10") + require.NoError(t, err) + t.Setenv("SOURCE_DATE_EPOCH", strconv.FormatInt(epoch.Unix(), 10)) + + require.NoError(t, copyFile(path.Join("fixtures", "buildx_stop.pre.md"), path.Join(tmpdir, "buildx_stop.md"))) + + c, err := New(Options{ + Root: dockerCmd, + SourceDir: tmpdir, + Plugin: true, + ManHeader: &doc.GenManHeader{ + Title: "DOCKER", + Section: "1", + Source: "Docker Community", + Manual: "Docker User Manuals", + }, + }) + require.NoError(t, err) + require.NoError(t, c.GenManTree(dockerCmd)) + + seen := make(map[string]struct{}) + remanpage := regexp.MustCompile(`\.\d+$`) + + filepath.Walk("fixtures", func(path string, info fs.FileInfo, err error) error { + fname := filepath.Base(path) + // ignore dirs and any file that is not a manpage + if info.IsDir() || !remanpage.MatchString(fname) { + return nil + } + t.Run(fname, func(t *testing.T) { + seen[fname] = struct{}{} + require.NoError(t, err) + + bres, err := os.ReadFile(filepath.Join(tmpdir, fname)) + require.NoError(t, err) + + bexc, err := os.ReadFile(path) + require.NoError(t, err) + assert.Equal(t, string(bexc), string(bres)) + }) + return nil + }) + + filepath.Walk(tmpdir, func(path string, info fs.FileInfo, err error) error { + fname := filepath.Base(path) + // ignore dirs and any file that is not a manpage + if info.IsDir() || !remanpage.MatchString(fname) { + return nil + } + t.Run("seen_"+fname, func(t *testing.T) { + if _, ok := seen[fname]; !ok { + t.Errorf("file %s not found in fixtures", fname) + } + }) + return nil + }) +} diff --git a/clidocstool_md_test.go b/clidocstool_md_test.go index 244611e..0900b51 100644 --- a/clidocstool_md_test.go +++ b/clidocstool_md_test.go @@ -27,17 +27,18 @@ import ( //nolint:errcheck func TestGenMarkdownTree(t *testing.T) { + setup() tmpdir := t.TempDir() require.NoError(t, copyFile(path.Join("fixtures", "buildx_stop.pre.md"), path.Join(tmpdir, "buildx_stop.md"))) c, err := New(Options{ - Root: buildxCmd, + Root: dockerCmd, SourceDir: tmpdir, Plugin: true, }) require.NoError(t, err) - require.NoError(t, c.GenMarkdownTree(buildxCmd)) + require.NoError(t, c.GenMarkdownTree(dockerCmd)) seen := make(map[string]struct{}) diff --git a/clidocstool_test.go b/clidocstool_test.go index e89de99..0fece8e 100644 --- a/clidocstool_test.go +++ b/clidocstool_test.go @@ -19,25 +19,30 @@ import ( "os" "path" "path/filepath" + "strconv" "strings" "testing" + "time" "github.com/docker/cli-docs-tool/annotation" "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) var ( - dockerCmd *cobra.Command - buildxCmd *cobra.Command - buildxBuildCmd *cobra.Command - buildxInstallCmd *cobra.Command - buildxStopCmd *cobra.Command + dockerCmd *cobra.Command + attachCmd *cobra.Command + buildxCmd *cobra.Command + buildxBuildCmd *cobra.Command + buildxDialStdioCmd *cobra.Command + buildxInstallCmd *cobra.Command + buildxStopCmd *cobra.Command ) //nolint:errcheck -func init() { +func setup() { dockerCmd = &cobra.Command{ Use: "docker [OPTIONS] COMMAND [ARG...]", Short: "A self-sufficient runtime for containers", @@ -48,6 +53,22 @@ func init() { Version: "20.10.8", DisableFlagsInUseLine: true, } + + attachCmd = &cobra.Command{ + Use: "attach [OPTIONS] CONTAINER", + Short: "Attach local standard input, output, and error streams to a running container", + Annotations: map[string]string{ + "aliases": "docker container attach, docker attach", + }, + Run: func(cmd *cobra.Command, args []string) {}, + } + + attachFlags := attachCmd.Flags() + attachFlags.Bool("no-stdin", false, "Do not attach STDIN") + attachFlags.Bool("sig-proxy", true, "Proxy all received signals to the process") + attachFlags.String("detach-keys", "", "Override the key sequence for detaching a container") + dockerCmd.AddCommand(attachCmd) + buildxCmd = &cobra.Command{ Use: "buildx", Short: "Docker Buildx", @@ -65,6 +86,12 @@ func init() { "aliases": "docker image build, docker buildx build, docker buildx b, docker build", }, } + buildxDialStdioCmd = &cobra.Command{ + Use: "dial-stdio", + Short: "Proxy current stdio streams to builder instance", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) {}, + } buildxInstallCmd = &cobra.Command{ Use: "install", Short: "Install buildx as a 'docker builder' alias", @@ -184,7 +211,13 @@ format: "default|[=|[,]]"`) buildxBuildFlags.BoolVar(&ignoreBool, "force-rm", false, "Always remove intermediate containers") buildxBuildFlags.MarkHidden("force-rm") + buildxDialStdioFlags := buildxDialStdioCmd.Flags() + + buildxDialStdioFlags.String("platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Target platform: this is used for node selection") + buildxDialStdioFlags.String("progress", "quiet", "Set type of progress output (auto, plain, tty).") + buildxCmd.AddCommand(buildxBuildCmd) + buildxCmd.AddCommand(buildxDialStdioCmd) buildxCmd.AddCommand(buildxInstallCmd) buildxCmd.AddCommand(buildxStopCmd) dockerCmd.AddCommand(buildxCmd) @@ -192,14 +225,25 @@ format: "default|[=|[,]]"`) //nolint:errcheck func TestGenAllTree(t *testing.T) { + setup() tmpdir := t.TempDir() + epoch, err := time.Parse("2006-Jan-02", "2020-Jan-10") + require.NoError(t, err) + t.Setenv("SOURCE_DATE_EPOCH", strconv.FormatInt(epoch.Unix(), 10)) + require.NoError(t, copyFile(path.Join("fixtures", "buildx_stop.pre.md"), path.Join(tmpdir, "buildx_stop.md"))) c, err := New(Options{ - Root: buildxCmd, + Root: dockerCmd, SourceDir: tmpdir, Plugin: true, + ManHeader: &doc.GenManHeader{ + Title: "DOCKER", + Section: "1", + Source: "Docker Community", + Manual: "Docker User Manuals", + }, }) require.NoError(t, err) require.NoError(t, c.GenAllTree()) diff --git a/clidocstool_yaml.go b/clidocstool_yaml.go index 5235242..acf5f2b 100644 --- a/clidocstool_yaml.go +++ b/clidocstool_yaml.go @@ -78,7 +78,7 @@ type cmdDoc struct { // it is undefined which help output will be in the file `cmd-sub-third.1`. func (c *Client) GenYamlTree(cmd *cobra.Command) error { emptyStr := func(s string) string { return "" } - if err := c.loadLongDescription(cmd); err != nil { + if err := c.loadLongDescription(cmd, "yaml"); err != nil { return err } return c.genYamlTreeCustom(cmd, emptyStr) @@ -371,63 +371,6 @@ func hasSeeAlso(cmd *cobra.Command) bool { return false } -// loadLongDescription gets long descriptions and examples from markdown. -func (c *Client) loadLongDescription(parentCmd *cobra.Command) error { - for _, cmd := range parentCmd.Commands() { - if cmd.HasSubCommands() { - if err := c.loadLongDescription(cmd); err != nil { - return err - } - } - name := cmd.CommandPath() - if i := strings.Index(name, " "); i >= 0 { - // remove root command / binary name - name = name[i+1:] - } - if name == "" { - continue - } - mdFile := strings.ReplaceAll(name, " ", "_") + ".md" - sourcePath := filepath.Join(c.source, mdFile) - content, err := os.ReadFile(sourcePath) - if os.IsNotExist(err) { - log.Printf("WARN: %s does not exist, skipping Markdown examples for YAML doc\n", mdFile) - continue - } - if err != nil { - return err - } - applyDescriptionAndExamples(cmd, string(content)) - } - return nil -} - -// applyDescriptionAndExamples fills in cmd.Long and cmd.Example with the -// "Description" and "Examples" H2 sections in mdString (if present). -func applyDescriptionAndExamples(cmd *cobra.Command, mdString string) { - sections := getSections(mdString) - var ( - anchors []string - md string - ) - if sections["description"] != "" { - md, anchors = cleanupMarkDown(sections["description"]) - cmd.Long = md - anchors = append(anchors, md) - } - if sections["examples"] != "" { - md, anchors = cleanupMarkDown(sections["examples"]) - cmd.Example = md - anchors = append(anchors, md) - } - if len(anchors) > 0 { - if cmd.Annotations == nil { - cmd.Annotations = make(map[string]string) - } - cmd.Annotations["anchors"] = strings.Join(anchors, ",") - } -} - type byName []*cobra.Command func (s byName) Len() int { return len(s) } diff --git a/clidocstool_yaml_test.go b/clidocstool_yaml_test.go index 4de872f..5554312 100644 --- a/clidocstool_yaml_test.go +++ b/clidocstool_yaml_test.go @@ -27,15 +27,16 @@ import ( //nolint:errcheck func TestGenYamlTree(t *testing.T) { + setup() tmpdir := t.TempDir() c, err := New(Options{ - Root: buildxCmd, + Root: dockerCmd, SourceDir: tmpdir, Plugin: true, }) require.NoError(t, err) - require.NoError(t, c.GenYamlTree(buildxCmd)) + require.NoError(t, c.GenYamlTree(dockerCmd)) seen := make(map[string]struct{}) diff --git a/example/go.mod b/example/go.mod index cd9561e..5b3d0ad 100644 --- a/example/go.mod +++ b/example/go.mod @@ -41,6 +41,7 @@ require ( github.com/containerd/continuity v0.4.1 // indirect github.com/containerd/ttrpc v1.2.2 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa // indirect @@ -111,6 +112,7 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect diff --git a/example/go.sum b/example/go.sum index ebf891c..e14ea27 100644 --- a/example/go.sum +++ b/example/go.sum @@ -136,6 +136,7 @@ github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtO github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= @@ -437,6 +438,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE= github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs= diff --git a/example/main.go b/example/main.go index 50caa6d..574476b 100644 --- a/example/main.go +++ b/example/main.go @@ -22,6 +22,7 @@ import ( clidocstool "github.com/docker/cli-docs-tool" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" "github.com/spf13/pflag" // import drivers otherwise factories are empty @@ -66,6 +67,12 @@ func gen(opts *options) error { SourceDir: opts.source, TargetDir: opts.target, Plugin: true, + ManHeader: &doc.GenManHeader{ + Title: "BUILDX", + Section: "1", + Source: "Docker Community", + Manual: "Docker User Manuals", + }, }) if err != nil { return err diff --git a/fixtures/attach.md b/fixtures/attach.md new file mode 100644 index 0000000..09ceeea --- /dev/null +++ b/fixtures/attach.md @@ -0,0 +1,20 @@ +# docker attach + + +Attach local standard input, output, and error streams to a running container + +### Aliases + +`docker container attach`, `docker attach` + +### Options + +| Name | Type | Default | Description | +|:----------------|:---------|:--------|:----------------------------------------------------| +| `--detach-keys` | `string` | | Override the key sequence for detaching a container | +| `--no-stdin` | `bool` | | Do not attach STDIN | +| `--sig-proxy` | `bool` | `true` | Proxy all received signals to the process | + + + + diff --git a/fixtures/buildx.md b/fixtures/buildx.md index 607fec9..548a7e8 100644 --- a/fixtures/buildx.md +++ b/fixtures/buildx.md @@ -5,10 +5,11 @@ Extended build capabilities with BuildKit ### Subcommands -| Name | Description | -|:---------------------------|:----------------------| -| [`build`](buildx_build.md) | Start a build | -| [`stop`](buildx_stop.md) | Stop builder instance | +| Name | Description | +|:-------------------------------------|:------------------------------------------------| +| [`build`](buildx_build.md) | Start a build | +| [`dial-stdio`](buildx_dial-stdio.md) | Proxy current stdio streams to builder instance | +| [`stop`](buildx_stop.md) | Stop builder instance | ### Options diff --git a/fixtures/buildx_dial-stdio.md b/fixtures/buildx_dial-stdio.md new file mode 100644 index 0000000..2930248 --- /dev/null +++ b/fixtures/buildx_dial-stdio.md @@ -0,0 +1,16 @@ +# docker buildx dial-stdio + + +Proxy current stdio streams to builder instance + +### Options + +| Name | Type | Default | Description | +|:-------------|:---------|:--------|:-------------------------------------------------| +| `--builder` | `string` | | Override the configured builder instance | +| `--platform` | `string` | | Target platform: this is used for node selection | +| `--progress` | `string` | `quiet` | Set type of progress output (auto, plain, tty). | + + + + diff --git a/fixtures/docker-attach.1 b/fixtures/docker-attach.1 new file mode 100644 index 0000000..2cac572 --- /dev/null +++ b/fixtures/docker-attach.1 @@ -0,0 +1,39 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-attach - Attach local standard input, output, and error streams to a running container + + +.SH SYNOPSIS +.PP +\fBdocker attach [OPTIONS] CONTAINER\fP + + +.SH DESCRIPTION +.PP +Attach local standard input, output, and error streams to a running container + + +.SH OPTIONS +.PP +\fB--detach-keys\fP="" + Override the key sequence for detaching a container + +.PP +\fB-h\fP, \fB--help\fP[=false] + help for attach + +.PP +\fB--no-stdin\fP[=false] + Do not attach STDIN + +.PP +\fB--sig-proxy\fP[=true] + Proxy all received signals to the process + + +.SH SEE ALSO +.PP +\fBdocker(1)\fP diff --git a/fixtures/docker-buildx-build.1 b/fixtures/docker-buildx-build.1 new file mode 100644 index 0000000..b69b6b5 --- /dev/null +++ b/fixtures/docker-buildx-build.1 @@ -0,0 +1,122 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-buildx-build - Start a build + + +.SH SYNOPSIS +.PP +\fBdocker buildx build [OPTIONS] PATH | URL | -\fP + + +.SH DESCRIPTION +.PP +Start a build + + +.SH OPTIONS +.PP +\fB--add-host\fP=[] + Add a custom host-to-IP mapping (format: 'host:ip') + +.PP +\fB--allow\fP=[] + Allow extra privileged entitlement (e.g., "network.host", "security.insecure") + +.PP +\fB--build-arg\fP=[] + Set build-time variables + +.PP +\fB--cache-from\fP=[] + External cache sources (e.g., "user/app:cache", "type=local,src=path/to/dir") + +.PP +\fB--cache-to\fP=[] + Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir") + +.PP +\fB--cgroup-parent\fP="" + Optional parent cgroup for the container + +.PP +\fB--detach\fP[=true] + Dummy flag that tests boolean flags with true as default + +.PP +\fB-f\fP, \fB--file\fP="" + Name of the Dockerfile (default: "PATH/Dockerfile") + +.PP +\fB-h\fP, \fB--help\fP[=false] + help for build + +.PP +\fB--iidfile\fP="" + Write the image ID to the file + +.PP +\fB--label\fP=[] + Set metadata for an image + +.PP +\fB--load\fP[=false] + Shorthand for "--output=type=docker" + +.PP +\fB--network\fP="default" + Set the networking mode for the "RUN" instructions during build + +.PP +\fB-o\fP, \fB--output\fP=[] + Output destination (format: "type=local,dest=path") + +.PP +\fB--platform\fP=[] + Set target platform for build + +.PP +\fB--push\fP[=false] + Shorthand for "--output=type=registry" + +.PP +\fB-q\fP, \fB--quiet\fP[=false] + Suppress the build output and print image ID on success + +.PP +\fB--secret\fP=[] + Secret file to expose to the build (format: "id=mysecret,src=/local/secret") + +.PP +\fB--shm-size\fP="" + Size of "/dev/shm" + +.PP +\fB--ssh\fP=[] + SSH agent socket or keys to expose to the build +format: "default|[=|[,]]" + +.PP +\fB-t\fP, \fB--tag\fP=[] + Name and optionally a tag (format: "name:tag") + +.PP +\fB--target\fP="" + Set the target build stage to build. + +.PP +\fB--ulimit\fP="" + Ulimit options + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB--builder\fP="" + Override the configured builder instance + + +.SH SEE ALSO +.PP +\fBdocker-buildx(1)\fP diff --git a/fixtures/docker-buildx-dial-stdio.1 b/fixtures/docker-buildx-dial-stdio.1 new file mode 100644 index 0000000..5c28476 --- /dev/null +++ b/fixtures/docker-buildx-dial-stdio.1 @@ -0,0 +1,41 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-buildx-dial-stdio - Proxy current stdio streams to builder instance + + +.SH SYNOPSIS +.PP +\fBdocker buildx dial-stdio\fP + + +.SH DESCRIPTION +.PP +Proxy current stdio streams to builder instance + + +.SH OPTIONS +.PP +\fB-h\fP, \fB--help\fP[=false] + help for dial-stdio + +.PP +\fB--platform\fP="" + Target platform: this is used for node selection + +.PP +\fB--progress\fP="quiet" + Set type of progress output (auto, plain, tty). + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB--builder\fP="" + Override the configured builder instance + + +.SH SEE ALSO +.PP +\fBdocker-buildx(1)\fP diff --git a/fixtures/docker-buildx-install.1 b/fixtures/docker-buildx-install.1 new file mode 100644 index 0000000..0f4a5df --- /dev/null +++ b/fixtures/docker-buildx-install.1 @@ -0,0 +1,33 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-buildx-install - Install buildx as a 'docker builder' alias + + +.SH SYNOPSIS +.PP +\fBdocker buildx install\fP + + +.SH DESCRIPTION +.PP +Install buildx as a 'docker builder' alias + + +.SH OPTIONS +.PP +\fB-h\fP, \fB--help\fP[=false] + help for install + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB--builder\fP="" + Override the configured builder instance + + +.SH SEE ALSO +.PP +\fBdocker-buildx(1)\fP diff --git a/fixtures/docker-buildx-stop.1 b/fixtures/docker-buildx-stop.1 new file mode 100644 index 0000000..a790e1f --- /dev/null +++ b/fixtures/docker-buildx-stop.1 @@ -0,0 +1,33 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-buildx-stop - Stop builder instance + + +.SH SYNOPSIS +.PP +\fBdocker buildx stop [NAME]\fP + + +.SH DESCRIPTION +.PP +Stop builder instance + + +.SH OPTIONS +.PP +\fB-h\fP, \fB--help\fP[=false] + help for stop + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB--builder\fP="" + Override the configured builder instance + + +.SH SEE ALSO +.PP +\fBdocker-buildx(1)\fP diff --git a/fixtures/docker-buildx.1 b/fixtures/docker-buildx.1 new file mode 100644 index 0000000..f7f4742 --- /dev/null +++ b/fixtures/docker-buildx.1 @@ -0,0 +1,31 @@ +.nh +.TH "DOCKER" "1" "Jan 2020" "Docker Community" "Docker User Manuals" + +.SH NAME +.PP +docker-buildx - Docker Buildx + + +.SH SYNOPSIS +.PP +\fBdocker buildx\fP + + +.SH DESCRIPTION +.PP +Extended build capabilities with BuildKit + + +.SH OPTIONS +.PP +\fB--builder\fP="" + Override the configured builder instance + +.PP +\fB-h\fP, \fB--help\fP[=false] + help for buildx + + +.SH SEE ALSO +.PP +\fBdocker(1)\fP, \fBdocker-buildx-build(1)\fP, \fBdocker-buildx-dial-stdio(1)\fP, \fBdocker-buildx-stop(1)\fP diff --git a/fixtures/docker_attach.yaml b/fixtures/docker_attach.yaml new file mode 100644 index 0000000..e950296 --- /dev/null +++ b/fixtures/docker_attach.yaml @@ -0,0 +1,46 @@ +command: docker attach +aliases: docker container attach, docker attach +short: | + Attach local standard input, output, and error streams to a running container +long: | + Attach local standard input, output, and error streams to a running container +usage: docker attach [OPTIONS] CONTAINER +pname: docker +plink: docker.yaml +options: + - option: detach-keys + value_type: string + description: Override the key sequence for detaching a container + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: no-stdin + value_type: bool + default_value: "false" + description: Do not attach STDIN + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: sig-proxy + value_type: bool + default_value: "true" + description: Proxy all received signals to the process + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/fixtures/docker_buildx.yaml b/fixtures/docker_buildx.yaml index c8b5cb5..93be880 100644 --- a/fixtures/docker_buildx.yaml +++ b/fixtures/docker_buildx.yaml @@ -5,9 +5,11 @@ pname: docker plink: docker.yaml cname: - docker buildx build + - docker buildx dial-stdio - docker buildx stop clink: - docker_buildx_build.yaml + - docker_buildx_dial-stdio.yaml - docker_buildx_stop.yaml options: - option: builder diff --git a/fixtures/docker_buildx_dial-stdio.yaml b/fixtures/docker_buildx_dial-stdio.yaml new file mode 100644 index 0000000..d9bc7e3 --- /dev/null +++ b/fixtures/docker_buildx_dial-stdio.yaml @@ -0,0 +1,43 @@ +command: docker buildx dial-stdio +short: Proxy current stdio streams to builder instance +long: Proxy current stdio streams to builder instance +usage: docker buildx dial-stdio +pname: docker buildx +plink: docker_buildx.yaml +options: + - option: platform + value_type: string + description: 'Target platform: this is used for node selection' + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: progress + value_type: string + default_value: quiet + description: Set type of progress output (auto, plain, tty). + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: builder + value_type: string + description: Override the configured builder instance + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/go.mod b/go.mod index cdaa8f7..220e79b 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,9 @@ require ( ) require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect ) diff --git a/go.sum b/go.sum index 813cf7d..adad808 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -6,6 +7,7 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=