You've already forked cli-docs-tool
mirror of
https://github.com/docker/cli-docs-tool.git
synced 2025-08-09 21:22:44 +03:00
New opts for setting target and plugin capabilities
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
1
.github/workflows/godev.yml
vendored
1
.github/workflows/godev.yml
vendored
@@ -9,6 +9,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
|
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
@@ -41,3 +41,20 @@ jobs:
|
|||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
file: ./coverage.txt
|
file: ./coverage.txt
|
||||||
|
|
||||||
|
example:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
-
|
||||||
|
name: Set up Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.16
|
||||||
|
-
|
||||||
|
name: Run
|
||||||
|
run: |
|
||||||
|
go run main.go
|
||||||
|
working-directory: ./example
|
||||||
|
57
README.md
57
README.md
@@ -41,61 +41,10 @@ require (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, create a file named `docgen.go` inside that directory containing the
|
Next, create a file named `main.go` inside that directory containing the
|
||||||
following Go code:
|
following Go code from [`example/main.go`](example/main.go).
|
||||||
|
|
||||||
```go
|
Running this example should produce the following output:
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/docker/buildx/commands"
|
|
||||||
"github.com/docker/cli/cli/command"
|
|
||||||
clidocstool "github.com/docker/cli-docs-tool"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
const sourcePath = "docs/"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.SetFlags(0)
|
|
||||||
|
|
||||||
dockerCLI, err := command.NewDockerCli()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ERROR: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "docker [OPTIONS] COMMAND [ARG...]",
|
|
||||||
Short: "The base command for the Docker CLI.",
|
|
||||||
DisableAutoGenTag: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.AddCommand(commands.NewRootCmd("buildx", true, dockerCLI))
|
|
||||||
clidocstool.DisableFlagsInUseLine(cmd)
|
|
||||||
|
|
||||||
cwd, _ := os.Getwd()
|
|
||||||
source := filepath.Join(cwd, sourcePath)
|
|
||||||
|
|
||||||
// Make sure "source" folder is created first
|
|
||||||
if err = os.MkdirAll(source, 0755); err != nil {
|
|
||||||
log.Printf("ERROR: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate Markdown and YAML documentation to "source" folder
|
|
||||||
if err = clidocstool.GenTree(cmd, source); err != nil {
|
|
||||||
log.Printf("ERROR: %+v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we create a new instance of Docker CLI with `command.NewDockerCli` and a
|
|
||||||
subcommand `commands.NewRootCmd` for `buildx`.
|
|
||||||
|
|
||||||
Finally, we generate Markdown and YAML documentation with `clidocstool.GenTree`.
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ go run main.go
|
$ go run main.go
|
||||||
|
106
clidocstool.go
106
clidocstool.go
@@ -15,38 +15,108 @@
|
|||||||
package clidocstool
|
package clidocstool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenTree creates yaml and markdown structured ref files for this command
|
// Options defines options for cli-docs-tool
|
||||||
// and all descendants in the directory given. This function will just
|
type Options struct {
|
||||||
// call GenMarkdownTree and GenYamlTree functions successively.
|
Root *cobra.Command
|
||||||
func GenTree(cmd *cobra.Command, dir string) error {
|
SourceDir string
|
||||||
|
TargetDir string
|
||||||
|
Plugin bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client represents an active cli-docs-tool object
|
||||||
|
type Client struct {
|
||||||
|
root *cobra.Command
|
||||||
|
source string
|
||||||
|
target string
|
||||||
|
plugin bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New initializes a new cli-docs-tool client
|
||||||
|
func New(opts Options) (*Client, error) {
|
||||||
|
if opts.Root == nil {
|
||||||
|
return nil, errors.New("root cmd required")
|
||||||
|
}
|
||||||
|
if len(opts.SourceDir) == 0 {
|
||||||
|
return nil, errors.New("source dir required")
|
||||||
|
}
|
||||||
|
c := &Client{
|
||||||
|
root: opts.Root,
|
||||||
|
source: opts.SourceDir,
|
||||||
|
plugin: opts.Plugin,
|
||||||
|
}
|
||||||
|
if len(opts.TargetDir) == 0 {
|
||||||
|
c.target = c.source
|
||||||
|
} else {
|
||||||
|
c.target = opts.TargetDir
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(c.target, 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenAllTree creates all structured ref files for this command and
|
||||||
|
// all descendants in the directory given.
|
||||||
|
func (c *Client) GenAllTree() error {
|
||||||
var err error
|
var err error
|
||||||
if err = GenMarkdownTree(cmd, dir); err != nil {
|
if err = c.GenMarkdownTree(c.root); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = GenYamlTree(cmd, dir); err != nil {
|
if err = c.GenYamlTree(c.root); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VisitAll will traverse all commands from the root.
|
|
||||||
// This is different from the VisitAll of cobra.Command where only parents
|
|
||||||
// are checked.
|
|
||||||
func VisitAll(root *cobra.Command, fn func(*cobra.Command)) {
|
|
||||||
for _, cmd := range root.Commands() {
|
|
||||||
VisitAll(cmd, fn)
|
|
||||||
}
|
|
||||||
fn(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableFlagsInUseLine sets the DisableFlagsInUseLine flag on all
|
// DisableFlagsInUseLine sets the DisableFlagsInUseLine flag on all
|
||||||
// commands within the tree rooted at cmd.
|
// commands within the tree rooted at cmd.
|
||||||
func DisableFlagsInUseLine(cmd *cobra.Command) {
|
func (c *Client) DisableFlagsInUseLine() {
|
||||||
VisitAll(cmd, func(ccmd *cobra.Command) {
|
visitAll(c.root, func(ccmd *cobra.Command) {
|
||||||
// do not add a `[flags]` to the end of the usage line.
|
// do not add a `[flags]` to the end of the usage line.
|
||||||
ccmd.DisableFlagsInUseLine = true
|
ccmd.DisableFlagsInUseLine = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// visitAll traverses all commands from the root.
|
||||||
|
// This is different from the VisitAll of cobra.Command where only parents
|
||||||
|
// are checked.
|
||||||
|
func visitAll(root *cobra.Command, fn func(*cobra.Command)) {
|
||||||
|
for _, cmd := range root.Commands() {
|
||||||
|
visitAll(cmd, fn)
|
||||||
|
}
|
||||||
|
fn(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(f string) bool {
|
||||||
|
info, err := os.Stat(f)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !info.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyFile(src string, dest string) error {
|
||||||
|
srcFile, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer srcFile.Close()
|
||||||
|
|
||||||
|
destFile, err := os.Create(dest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer destFile.Close()
|
||||||
|
|
||||||
|
if _, err = io.Copy(destFile, srcFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return destFile.Sync()
|
||||||
|
}
|
||||||
|
@@ -31,21 +31,25 @@ import (
|
|||||||
|
|
||||||
// GenMarkdownTree will generate a markdown page for this command and all
|
// GenMarkdownTree will generate a markdown page for this command and all
|
||||||
// descendants in the directory given.
|
// descendants in the directory given.
|
||||||
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
func (c *Client) GenMarkdownTree(cmd *cobra.Command) error {
|
||||||
for _, c := range cmd.Commands() {
|
for _, sc := range cmd.Commands() {
|
||||||
if err := GenMarkdownTree(c, dir); err != nil {
|
if err := c.GenMarkdownTree(sc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !cmd.HasParent() {
|
|
||||||
|
// Skip the root command altogether, to prevent generating a useless
|
||||||
|
// md file for plugins.
|
||||||
|
if c.plugin && !cmd.HasParent() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("INFO: Generating Markdown for %q", cmd.CommandPath())
|
log.Printf("INFO: Generating Markdown for %q", cmd.CommandPath())
|
||||||
mdFile := mdFilename(cmd)
|
mdFile := mdFilename(cmd)
|
||||||
fullPath := filepath.Join(dir, mdFile)
|
sourcePath := filepath.Join(c.source, mdFile)
|
||||||
|
targetPath := filepath.Join(c.target, mdFile)
|
||||||
|
|
||||||
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
|
if !fileExists(sourcePath) {
|
||||||
var icBuf bytes.Buffer
|
var icBuf bytes.Buffer
|
||||||
icTpl, err := template.New("ic").Option("missingkey=error").Parse(`# {{ .Command }}
|
icTpl, err := template.New("ic").Option("missingkey=error").Parse(`# {{ .Command }}
|
||||||
|
|
||||||
@@ -63,12 +67,14 @@ func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = ioutil.WriteFile(fullPath, icBuf.Bytes(), 0644); err != nil {
|
if err = ioutil.WriteFile(targetPath, icBuf.Bytes(), 0644); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if err := copyFile(sourcePath, targetPath); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := ioutil.ReadFile(fullPath)
|
content, err := ioutil.ReadFile(targetPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -91,12 +97,12 @@ func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
|||||||
}
|
}
|
||||||
cont := cs[:start] + "<!---MARKER_GEN_START-->" + "\n" + out + "\n" + cs[end:]
|
cont := cs[:start] + "<!---MARKER_GEN_START-->" + "\n" + out + "\n" + cs[end:]
|
||||||
|
|
||||||
fi, err := os.Stat(fullPath)
|
fi, err := os.Stat(targetPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(fullPath, []byte(cont), fi.Mode()); err != nil {
|
if err = ioutil.WriteFile(targetPath, []byte(cont), fi.Mode()); err != nil {
|
||||||
return errors.Wrapf(err, "failed to write %s", fullPath)
|
return errors.Wrapf(err, "failed to write %s", targetPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -17,67 +17,39 @@ package clidocstool
|
|||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:errcheck
|
//nolint:errcheck
|
||||||
func TestGenMarkdownTree(t *testing.T) {
|
func TestGenMarkdownTree(t *testing.T) {
|
||||||
c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
|
|
||||||
s := &cobra.Command{Use: "sub [OPTIONS] arg1 arg2"}
|
|
||||||
|
|
||||||
flags := s.Flags()
|
|
||||||
_ = flags.Bool("push", false, "Shorthand for --output=type=registry")
|
|
||||||
_ = flags.Bool("load", false, "Shorthand for --output=type=docker")
|
|
||||||
_ = flags.StringArrayP("tag", "t", []string{}, "Name and optionally a tag in the 'name:tag' format")
|
|
||||||
flags.SetAnnotation("tag", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t"})
|
|
||||||
_ = flags.StringArray("build-arg", []string{}, "Set build-time variables")
|
|
||||||
flags.SetAnnotation("build-arg", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg"})
|
|
||||||
_ = flags.StringP("file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
|
|
||||||
flags.SetAnnotation("file", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f"})
|
|
||||||
_ = flags.StringArray("label", []string{}, "Set metadata for an image")
|
|
||||||
_ = flags.StringArray("cache-from", []string{}, "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
|
|
||||||
_ = flags.StringArray("cache-to", []string{}, "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)")
|
|
||||||
_ = flags.String("target", "", "Set the target build stage to build.")
|
|
||||||
flags.SetAnnotation("target", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target"})
|
|
||||||
_ = flags.StringSlice("allow", []string{}, "Allow extra privileged entitlement, e.g. network.host, security.insecure")
|
|
||||||
_ = flags.StringArray("platform", []string{}, "Set target platform for build")
|
|
||||||
_ = flags.StringArray("secret", []string{}, "Secret file to expose to the build: id=mysecret,src=/local/secret")
|
|
||||||
_ = flags.StringArray("ssh", []string{}, "SSH agent socket or keys to expose to the build (format: `default|<id>[=<socket>|<key>[,<key>]]`)")
|
|
||||||
_ = flags.StringArrayP("output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
|
||||||
// not implemented
|
|
||||||
_ = flags.String("network", "default", "Set the networking mode for the RUN instructions during build")
|
|
||||||
_ = flags.StringSlice("add-host", []string{}, "Add a custom host-to-IP mapping (host:ip)")
|
|
||||||
_ = flags.SetAnnotation("add-host", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host"})
|
|
||||||
_ = flags.String("iidfile", "", "Write the image ID to the file")
|
|
||||||
// hidden flags
|
|
||||||
_ = flags.BoolP("quiet", "q", false, "Suppress the build output and print image ID on success")
|
|
||||||
flags.MarkHidden("quiet")
|
|
||||||
_ = flags.Bool("squash", false, "Squash newly built layers into a single new layer")
|
|
||||||
flags.MarkHidden("squash")
|
|
||||||
_ = flags.String("ulimit", "", "Ulimit options")
|
|
||||||
flags.MarkHidden("ulimit")
|
|
||||||
_ = flags.StringSlice("security-opt", []string{}, "Security options")
|
|
||||||
flags.MarkHidden("security-opt")
|
|
||||||
_ = flags.Bool("compress", false, "Compress the build context using gzip")
|
|
||||||
|
|
||||||
c.AddCommand(s)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "test-gen-markdown-tree")
|
tmpdir, err := ioutil.TempDir("", "test-gen-markdown-tree")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
require.NoError(t, GenMarkdownTree(c, tmpdir))
|
|
||||||
|
|
||||||
fres := filepath.Join(tmpdir, "sub.md")
|
c, err := New(Options{
|
||||||
require.FileExists(t, fres)
|
Root: buildxCmd,
|
||||||
bres, err := ioutil.ReadFile(fres)
|
SourceDir: tmpdir,
|
||||||
|
Plugin: true,
|
||||||
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
bexc, err := ioutil.ReadFile("fixtures/sub.md")
|
require.NoError(t, c.GenMarkdownTree(buildxCmd))
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, string(bres), string(bexc))
|
for _, tt := range []string{"buildx.md", "buildx_build.md"} {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt, func(t *testing.T) {
|
||||||
|
fres := filepath.Join(tmpdir, tt)
|
||||||
|
require.FileExists(t, fres)
|
||||||
|
bres, err := ioutil.ReadFile(fres)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
bexc, err := ioutil.ReadFile(path.Join("fixtures", tt))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, string(bexc), string(bres))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
124
clidocstool_test.go
Normal file
124
clidocstool_test.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// Copyright 2021 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/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dockerCmd *cobra.Command
|
||||||
|
buildxCmd *cobra.Command
|
||||||
|
buildxBuildCmd *cobra.Command
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:errcheck
|
||||||
|
func init() {
|
||||||
|
dockerCmd = &cobra.Command{
|
||||||
|
Use: "docker [OPTIONS] COMMAND [ARG...]",
|
||||||
|
Short: "A self-sufficient runtime for containers",
|
||||||
|
SilenceUsage: true,
|
||||||
|
SilenceErrors: true,
|
||||||
|
TraverseChildren: true,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {},
|
||||||
|
Version: "20.10.8",
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
}
|
||||||
|
buildxCmd = &cobra.Command{
|
||||||
|
Use: "buildx",
|
||||||
|
Short: "Build with BuildKit",
|
||||||
|
}
|
||||||
|
buildxBuildCmd = &cobra.Command{
|
||||||
|
Use: "build [OPTIONS] PATH | URL | -",
|
||||||
|
Aliases: []string{"b"},
|
||||||
|
Short: "Start a build",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {},
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := buildxBuildCmd.Flags()
|
||||||
|
flags.Bool("push", false, "Shorthand for --output=type=registry")
|
||||||
|
flags.Bool("load", false, "Shorthand for --output=type=docker")
|
||||||
|
flags.StringArrayP("tag", "t", []string{}, "Name and optionally a tag in the 'name:tag' format")
|
||||||
|
flags.SetAnnotation("tag", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t"})
|
||||||
|
flags.StringArray("build-arg", []string{}, "Set build-time variables")
|
||||||
|
flags.SetAnnotation("build-arg", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg"})
|
||||||
|
flags.StringP("file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
|
||||||
|
flags.SetAnnotation("file", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f"})
|
||||||
|
flags.StringArray("label", []string{}, "Set metadata for an image")
|
||||||
|
flags.StringArray("cache-from", []string{}, "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
|
||||||
|
flags.StringArray("cache-to", []string{}, "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)")
|
||||||
|
flags.String("target", "", "Set the target build stage to build.")
|
||||||
|
flags.SetAnnotation("target", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target"})
|
||||||
|
flags.StringSlice("allow", []string{}, "Allow extra privileged entitlement, e.g. network.host, security.insecure")
|
||||||
|
flags.StringArray("platform", []string{}, "Set target platform for build")
|
||||||
|
flags.StringArray("secret", []string{}, "Secret file to expose to the build: id=mysecret,src=/local/secret")
|
||||||
|
flags.StringArray("ssh", []string{}, "SSH agent socket or keys to expose to the build (format: `default|<id>[=<socket>|<key>[,<key>]]`)")
|
||||||
|
flags.StringArrayP("output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
||||||
|
// not implemented
|
||||||
|
flags.String("network", "default", "Set the networking mode for the RUN instructions during build")
|
||||||
|
flags.StringSlice("add-host", []string{}, "Add a custom host-to-IP mapping (host:ip)")
|
||||||
|
flags.SetAnnotation("add-host", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host"})
|
||||||
|
flags.String("iidfile", "", "Write the image ID to the file")
|
||||||
|
// hidden flags
|
||||||
|
flags.BoolP("quiet", "q", false, "Suppress the build output and print image ID on success")
|
||||||
|
flags.MarkHidden("quiet")
|
||||||
|
flags.Bool("squash", false, "Squash newly built layers into a single new layer")
|
||||||
|
flags.MarkHidden("squash")
|
||||||
|
flags.String("ulimit", "", "Ulimit options")
|
||||||
|
flags.MarkHidden("ulimit")
|
||||||
|
flags.StringSlice("security-opt", []string{}, "Security options")
|
||||||
|
flags.MarkHidden("security-opt")
|
||||||
|
flags.Bool("compress", false, "Compress the build context using gzip")
|
||||||
|
|
||||||
|
buildxCmd.AddCommand(buildxBuildCmd)
|
||||||
|
dockerCmd.AddCommand(buildxCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:errcheck
|
||||||
|
func TestGenAllTree(t *testing.T) {
|
||||||
|
tmpdir, err := ioutil.TempDir("", "test-gen-all-tree")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
c, err := New(Options{
|
||||||
|
Root: buildxCmd,
|
||||||
|
SourceDir: tmpdir,
|
||||||
|
Plugin: true,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, c.GenAllTree())
|
||||||
|
|
||||||
|
for _, tt := range []string{"buildx.md", "buildx_build.md", "docker_buildx.yaml", "docker_buildx_build.yaml"} {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt, func(t *testing.T) {
|
||||||
|
fres := filepath.Join(tmpdir, tt)
|
||||||
|
require.FileExists(t, fres)
|
||||||
|
bres, err := ioutil.ReadFile(fres)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
bexc, err := ioutil.ReadFile(path.Join("fixtures", tt))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, string(bexc), string(bres))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -74,62 +74,58 @@ type cmdDoc struct {
|
|||||||
// correctly if your command names have `-` in them. If you have `cmd` with two
|
// correctly if your command names have `-` in them. If you have `cmd` with two
|
||||||
// subcmds, `sub` and `sub-third`, and `sub` has a subcommand called `third`
|
// subcmds, `sub` and `sub-third`, and `sub` has a subcommand called `third`
|
||||||
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
||||||
func GenYamlTree(cmd *cobra.Command, dir string) error {
|
func (c *Client) GenYamlTree(cmd *cobra.Command) error {
|
||||||
emptyStr := func(s string) string { return "" }
|
emptyStr := func(s string) string { return "" }
|
||||||
if err := loadLongDescription(cmd, dir); err != nil {
|
if err := c.loadLongDescription(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return GenYamlTreeCustom(cmd, dir, emptyStr)
|
return c.genYamlTreeCustom(cmd, emptyStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenYamlTreeCustom creates yaml structured ref files.
|
// genYamlTreeCustom creates yaml structured ref files.
|
||||||
func GenYamlTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string) error {
|
func (c *Client) genYamlTreeCustom(cmd *cobra.Command, filePrepender func(string) string) error {
|
||||||
for _, c := range cmd.Commands() {
|
for _, sc := range cmd.Commands() {
|
||||||
if !c.Runnable() && !c.HasAvailableSubCommands() {
|
if !sc.Runnable() && !sc.HasAvailableSubCommands() {
|
||||||
// skip non-runnable commands without subcommands
|
// skip non-runnable commands without subcommands
|
||||||
// but *do* generate YAML for hidden and deprecated commands
|
// but *do* generate YAML for hidden and deprecated commands
|
||||||
// the YAML will have those included as metadata, so that the
|
// the YAML will have those included as metadata, so that the
|
||||||
// documentation repository can decide whether or not to present them
|
// documentation repository can decide whether or not to present them
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := GenYamlTreeCustom(c, dir, filePrepender); err != nil {
|
if err := c.genYamlTreeCustom(sc, filePrepender); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: conditionally skip the root command (for plugins)
|
|
||||||
//
|
|
||||||
// The "root" command used in the generator is just a "stub", and only has a
|
// The "root" command used in the generator is just a "stub", and only has a
|
||||||
// list of subcommands, but not (e.g.) global options/flags. We should fix
|
// list of subcommands, but not (e.g.) global options/flags. We should fix
|
||||||
// that, so that the YAML file for the docker "root" command contains the
|
// that, so that the YAML file for the docker "root" command contains the
|
||||||
// global flags.
|
// global flags.
|
||||||
//
|
|
||||||
// If we're using this code to generate YAML docs for a plugin, the root-
|
// Skip the root command altogether, to prevent generating a useless
|
||||||
// command is even less useful; in that case, the root command represents
|
// YAML file for plugins.
|
||||||
// the "docker" command, and is a "dummy" with no flags, and only a single
|
if c.plugin && !cmd.HasParent() {
|
||||||
// subcommand (the plugin's top command). For plugins, we should skip the
|
|
||||||
// root command altogether, to prevent generating a useless YAML file.
|
|
||||||
if !cmd.HasParent() {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("INFO: Generating YAML for %q", cmd.CommandPath())
|
log.Printf("INFO: Generating YAML for %q", cmd.CommandPath())
|
||||||
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".yaml"
|
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".yaml"
|
||||||
filename := filepath.Join(dir, basename)
|
target := filepath.Join(c.target, basename)
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
|
if _, err := io.WriteString(f, filePrepender(target)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return GenYamlCustom(cmd, f)
|
return c.genYamlCustom(cmd, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenYamlCustom creates custom yaml output.
|
// genYamlCustom creates custom yaml output.
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func GenYamlCustom(cmd *cobra.Command, w io.Writer) error {
|
func (c *Client) genYamlCustom(cmd *cobra.Command, w io.Writer) error {
|
||||||
const (
|
const (
|
||||||
// shortMaxWidth is the maximum width for the "Short" description before
|
// shortMaxWidth is the maximum width for the "Short" description before
|
||||||
// we force YAML to use multi-line syntax. The goal is to make the total
|
// we force YAML to use multi-line syntax. The goal is to make the total
|
||||||
@@ -338,15 +334,15 @@ func hasSeeAlso(cmd *cobra.Command) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadLongDescription gets long descriptions and examples from markdown.
|
// loadLongDescription gets long descriptions and examples from markdown.
|
||||||
func loadLongDescription(parentCmd *cobra.Command, path string) error {
|
func (c *Client) loadLongDescription(parentCmd *cobra.Command) error {
|
||||||
for _, cmd := range parentCmd.Commands() {
|
for _, cmd := range parentCmd.Commands() {
|
||||||
if cmd.HasSubCommands() {
|
if cmd.HasSubCommands() {
|
||||||
if err := loadLongDescription(cmd, path); err != nil {
|
if err := c.loadLongDescription(cmd); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name := cmd.CommandPath()
|
name := cmd.CommandPath()
|
||||||
if i := strings.Index(name, " "); i >= 0 {
|
if i := strings.Index(name, " "); c.plugin && i >= 0 {
|
||||||
// remove root command / binary name
|
// remove root command / binary name
|
||||||
name = name[i+1:]
|
name = name[i+1:]
|
||||||
}
|
}
|
||||||
@@ -354,8 +350,8 @@ func loadLongDescription(parentCmd *cobra.Command, path string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mdFile := strings.ReplaceAll(name, " ", "_") + ".md"
|
mdFile := strings.ReplaceAll(name, " ", "_") + ".md"
|
||||||
fullPath := filepath.Join(path, mdFile)
|
sourcePath := filepath.Join(c.source, mdFile)
|
||||||
content, err := ioutil.ReadFile(fullPath)
|
content, err := ioutil.ReadFile(sourcePath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
log.Printf("WARN: %s does not exist, skipping Markdown examples for YAML doc\n", mdFile)
|
log.Printf("WARN: %s does not exist, skipping Markdown examples for YAML doc\n", mdFile)
|
||||||
continue
|
continue
|
||||||
|
@@ -17,67 +17,39 @@ package clidocstool
|
|||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:errcheck
|
//nolint:errcheck
|
||||||
func TestGenYamlTree(t *testing.T) {
|
func TestGenYamlTree(t *testing.T) {
|
||||||
c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
|
|
||||||
s := &cobra.Command{Use: "sub [OPTIONS] arg1 arg2", Run: func(cmd *cobra.Command, args []string) {}}
|
|
||||||
|
|
||||||
flags := s.Flags()
|
|
||||||
_ = flags.Bool("push", false, "Shorthand for --output=type=registry")
|
|
||||||
_ = flags.Bool("load", false, "Shorthand for --output=type=docker")
|
|
||||||
_ = flags.StringArrayP("tag", "t", []string{}, "Name and optionally a tag in the 'name:tag' format")
|
|
||||||
flags.SetAnnotation("tag", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t"})
|
|
||||||
_ = flags.StringArray("build-arg", []string{}, "Set build-time variables")
|
|
||||||
flags.SetAnnotation("build-arg", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg"})
|
|
||||||
_ = flags.StringP("file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
|
|
||||||
flags.SetAnnotation("file", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f"})
|
|
||||||
_ = flags.StringArray("label", []string{}, "Set metadata for an image")
|
|
||||||
_ = flags.StringArray("cache-from", []string{}, "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
|
|
||||||
_ = flags.StringArray("cache-to", []string{}, "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)")
|
|
||||||
_ = flags.String("target", "", "Set the target build stage to build.")
|
|
||||||
flags.SetAnnotation("target", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target"})
|
|
||||||
_ = flags.StringSlice("allow", []string{}, "Allow extra privileged entitlement, e.g. network.host, security.insecure")
|
|
||||||
_ = flags.StringArray("platform", []string{}, "Set target platform for build")
|
|
||||||
_ = flags.StringArray("secret", []string{}, "Secret file to expose to the build: id=mysecret,src=/local/secret")
|
|
||||||
_ = flags.StringArray("ssh", []string{}, "SSH agent socket or keys to expose to the build (format: `default|<id>[=<socket>|<key>[,<key>]]`)")
|
|
||||||
_ = flags.StringArrayP("output", "o", []string{}, "Output destination (format: type=local,dest=path)")
|
|
||||||
// not implemented
|
|
||||||
_ = flags.String("network", "default", "Set the networking mode for the RUN instructions during build")
|
|
||||||
_ = flags.StringSlice("add-host", []string{}, "Add a custom host-to-IP mapping (host:ip)")
|
|
||||||
_ = flags.SetAnnotation("add-host", "docs.external.url", []string{"https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host"})
|
|
||||||
_ = flags.String("iidfile", "", "Write the image ID to the file")
|
|
||||||
// hidden flags
|
|
||||||
_ = flags.BoolP("quiet", "q", false, "Suppress the build output and print image ID on success")
|
|
||||||
flags.MarkHidden("quiet")
|
|
||||||
_ = flags.Bool("squash", false, "Squash newly built layers into a single new layer")
|
|
||||||
flags.MarkHidden("squash")
|
|
||||||
_ = flags.String("ulimit", "", "Ulimit options")
|
|
||||||
flags.MarkHidden("ulimit")
|
|
||||||
_ = flags.StringSlice("security-opt", []string{}, "Security options")
|
|
||||||
flags.MarkHidden("security-opt")
|
|
||||||
_ = flags.Bool("compress", false, "Compress the build context using gzip")
|
|
||||||
|
|
||||||
c.AddCommand(s)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "test-gen-yaml-tree")
|
tmpdir, err := ioutil.TempDir("", "test-gen-yaml-tree")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
require.NoError(t, GenYamlTree(c, tmpdir))
|
|
||||||
|
|
||||||
fres := filepath.Join(tmpdir, "do_sub.yaml")
|
c, err := New(Options{
|
||||||
require.FileExists(t, fres)
|
Root: buildxCmd,
|
||||||
bres, err := ioutil.ReadFile(fres)
|
SourceDir: tmpdir,
|
||||||
|
Plugin: true,
|
||||||
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
bexc, err := ioutil.ReadFile("fixtures/do_sub.yaml")
|
require.NoError(t, c.GenYamlTree(buildxCmd))
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, string(bres), string(bexc))
|
for _, tt := range []string{"docker_buildx.yaml", "docker_buildx_build.yaml"} {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt, func(t *testing.T) {
|
||||||
|
fres := filepath.Join(tmpdir, tt)
|
||||||
|
require.FileExists(t, fres)
|
||||||
|
bres, err := ioutil.ReadFile(fres)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
bexc, err := ioutil.ReadFile(path.Join("fixtures", tt))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, string(bexc), string(bres))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Example
|
# Example
|
||||||
|
|
||||||
The following example will generate YAML and Markdown docs for
|
The following example will generate all supported docs for
|
||||||
[Docker buildx](https://github.com/docker/buildx) CLI.
|
[Docker buildx](https://github.com/docker/buildx) CLI.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
|
@@ -3,14 +3,15 @@ module github.com/docker/cli-docs-tool/example
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/docker/buildx v0.6.0
|
github.com/docker/buildx v0.6.3
|
||||||
github.com/docker/cli v20.10.7+incompatible
|
github.com/docker/cli v20.10.7+incompatible
|
||||||
github.com/docker/cli-docs-tool v0.0.0
|
github.com/docker/cli-docs-tool v0.0.0
|
||||||
github.com/spf13/cobra v1.2.1
|
github.com/spf13/cobra v1.2.1
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
github.com/docker/cli => github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible
|
github.com/docker/cli => github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible
|
||||||
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20210609100121-ef4d47340142+incompatible
|
|
||||||
github.com/docker/cli-docs-tool => ../
|
github.com/docker/cli-docs-tool => ../
|
||||||
|
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20210609100121-ef4d47340142+incompatible
|
||||||
)
|
)
|
||||||
|
@@ -69,8 +69,9 @@ github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEY
|
|||||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||||
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||||
github.com/Microsoft/hcsshim v0.8.16 h1:8/auA4LFIZFTGrqfKhGBSXwM6/4X1fHa/xniyEHu8ac=
|
|
||||||
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
||||||
|
github.com/Microsoft/hcsshim v0.8.18 h1:cYnKADiM1869gvBpos3YCteeT6sZLB48lB5dmMMs8Tg=
|
||||||
|
github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
@@ -151,8 +152,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
|||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20210706130854-69459d4976b5 h1:PpI72CT1bcVPNZyqI1HI8UhQVRVtqLb2tdwi5WphN3c=
|
github.com/compose-spec/compose-go v0.0.0-20210729195839-de56f4f0cb3c h1:lSR4wokZlq+Q8uJpgZuFMs3VoLaYVV07cJOZHa1zRBg=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20210706130854-69459d4976b5/go.mod h1:5V65rPnTvvQagtoMxTneJ2QicLq6ZRQQ7fOgPN226fo=
|
github.com/compose-spec/compose-go v0.0.0-20210729195839-de56f4f0cb3c/go.mod h1:5V65rPnTvvQagtoMxTneJ2QicLq6ZRQQ7fOgPN226fo=
|
||||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
@@ -186,8 +187,10 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7
|
|||||||
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
|
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
|
||||||
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
||||||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||||
github.com/containerd/containerd v1.5.2 h1:MG/Bg1pbmMb61j3wHCFWPxESXHieiKr2xG64px/k8zQ=
|
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||||
github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||||
|
github.com/containerd/containerd v1.5.4 h1:uPF0og3ByFzDnaStfiQj3fVGTEtaSNyU+bW7GR/nqGA=
|
||||||
|
github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
@@ -282,8 +285,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
|||||||
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=
|
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=
|
||||||
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=
|
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/buildx v0.6.0 h1:UuJvtuK8SQX/7Y9i1fJR3Jq6kXBSFcSJtudlALu9iV8=
|
github.com/docker/buildx v0.6.3 h1:/PReewxhHiBdNQmg6E9lUa56wKba0oXRBrKhwA90JXE=
|
||||||
github.com/docker/buildx v0.6.0/go.mod h1:ue0mOStExTp8vSb1wrvbpL9VoL0e66EK9etSCCIhuFM=
|
github.com/docker/buildx v0.6.3/go.mod h1:7gkFFXWFWo+vfXMNijFRBO0KwEDITP10TUWty5ZJNz0=
|
||||||
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible h1:CaaxCD/l9Dxogu6lxf7AQautlv3sHULrasPadayp0fM=
|
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible h1:CaaxCD/l9Dxogu6lxf7AQautlv3sHULrasPadayp0fM=
|
||||||
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 h1:90ytrX1dbzL7Uf/hHiuWwvywC+gikHv4hkAy4CwRTbs=
|
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 h1:90ytrX1dbzL7Uf/hHiuWwvywC+gikHv4hkAy4CwRTbs=
|
||||||
|
@@ -17,40 +17,72 @@ package main
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/docker/buildx/commands"
|
"github.com/docker/buildx/commands"
|
||||||
clidocstool "github.com/docker/cli-docs-tool"
|
clidocstool "github.com/docker/cli-docs-tool"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
const sourcePath = "docs/"
|
const (
|
||||||
|
pluginName = "buildx"
|
||||||
|
defaultSourcePath = "docs/"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
type options struct {
|
||||||
|
source string
|
||||||
|
target string
|
||||||
|
}
|
||||||
|
|
||||||
|
func gen(opts *options) error {
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
|
|
||||||
|
// create a new instance of Docker CLI
|
||||||
dockerCLI, err := command.NewDockerCli()
|
dockerCLI, err := command.NewDockerCli()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ERROR: %+v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// root command
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "docker [OPTIONS] COMMAND [ARG...]",
|
Use: "buildx",
|
||||||
Short: "The base command for the Docker CLI.",
|
Short: "Build with BuildKit",
|
||||||
DisableAutoGenTag: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(commands.NewRootCmd("buildx", true, dockerCLI))
|
// subcommand for the plugin
|
||||||
clidocstool.DisableFlagsInUseLine(cmd)
|
cmd.AddCommand(commands.NewRootCmd(pluginName, true, dockerCLI))
|
||||||
|
|
||||||
cwd, _ := os.Getwd()
|
// create a new instance of cli-docs-tool
|
||||||
source := filepath.Join(cwd, sourcePath)
|
c, err := clidocstool.New(clidocstool.Options{
|
||||||
|
Root: cmd,
|
||||||
if err = os.MkdirAll(source, 0755); err != nil {
|
SourceDir: opts.source,
|
||||||
log.Printf("ERROR: %+v", err)
|
TargetDir: opts.target,
|
||||||
|
Plugin: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err = clidocstool.GenTree(cmd, source); err != nil {
|
c.DisableFlagsInUseLine()
|
||||||
|
|
||||||
|
// generate all supported docs formats
|
||||||
|
return c.GenAllTree()
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
opts := &options{}
|
||||||
|
flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
|
||||||
|
flags.StringVar(&opts.source, "source", defaultSourcePath, "Docs source folder")
|
||||||
|
flags.StringVar(&opts.target, "target", defaultSourcePath, "Docs target folder")
|
||||||
|
if err := flags.Parse(os.Args[1:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return gen(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := run(); err != nil {
|
||||||
log.Printf("ERROR: %+v", err)
|
log.Printf("ERROR: %+v", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
fixtures/buildx.md
Normal file
15
fixtures/buildx.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# docker buildx
|
||||||
|
|
||||||
|
<!---MARKER_GEN_START-->
|
||||||
|
Build with BuildKit
|
||||||
|
|
||||||
|
### Subcommands
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| [`build`](buildx_build.md) | Start a build |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!---MARKER_GEN_END-->
|
||||||
|
|
@@ -1,6 +1,12 @@
|
|||||||
# do sub
|
# docker buildx build
|
||||||
|
|
||||||
<!---MARKER_GEN_START-->
|
<!---MARKER_GEN_START-->
|
||||||
|
Start a build
|
||||||
|
|
||||||
|
### Aliases
|
||||||
|
|
||||||
|
`build`, `b`
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
15
fixtures/docker_buildx.yaml
Normal file
15
fixtures/docker_buildx.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
command: docker buildx
|
||||||
|
short: Build with BuildKit
|
||||||
|
long: Build with BuildKit
|
||||||
|
pname: docker
|
||||||
|
plink: docker.yaml
|
||||||
|
cname:
|
||||||
|
- docker buildx build
|
||||||
|
clink:
|
||||||
|
- docker_buildx_build.yaml
|
||||||
|
deprecated: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
|
@@ -1,7 +1,10 @@
|
|||||||
command: do sub
|
command: docker buildx build
|
||||||
usage: do sub [OPTIONS] arg1 arg2 [flags]
|
aliases: b
|
||||||
pname: do
|
short: Start a build
|
||||||
plink: do.yaml
|
long: Start a build
|
||||||
|
usage: docker buildx build [OPTIONS] PATH | URL | - [flags]
|
||||||
|
pname: docker buildx
|
||||||
|
plink: docker_buildx.yaml
|
||||||
options:
|
options:
|
||||||
- option: add-host
|
- option: add-host
|
||||||
value_type: stringSlice
|
value_type: stringSlice
|
Reference in New Issue
Block a user