package plugin import ( "encoding/json" "fmt" "os" "github.com/docker/cli/cli" "github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli/command" cliflags "github.com/docker/cli/cli/flags" "github.com/spf13/cobra" "github.com/spf13/pflag" ) // Run is the top-level entry point to the CLI plugin framework. It should be called from your plugin's `main()` function. func Run(makeCmd func(command.Cli) *cobra.Command, meta manager.Metadata) { dockerCli, err := command.NewDockerCli() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } plugin := makeCmd(dockerCli) cmd := newPluginCommand(dockerCli, plugin, meta) if err := cmd.Execute(); err != nil { if sterr, ok := err.(cli.StatusError); ok { if sterr.Status != "" { fmt.Fprintln(dockerCli.Err(), sterr.Status) } // StatusError should only be used for errors, and all errors should // have a non-zero exit status, so never exit with 0 if sterr.StatusCode == 0 { os.Exit(1) } os.Exit(sterr.StatusCode) } fmt.Fprintln(dockerCli.Err(), err) os.Exit(1) } } func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) *cobra.Command { var ( opts *cliflags.ClientOptions flags *pflag.FlagSet ) name := plugin.Use fullname := manager.NamePrefix + name cmd := &cobra.Command{ Use: fmt.Sprintf("docker [OPTIONS] %s [ARG...]", name), Short: fullname + " is a Docker CLI plugin", SilenceUsage: true, SilenceErrors: true, TraverseChildren: true, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // flags must be the top-level command flags, not cmd.Flags() opts.Common.SetDefaultOptions(flags) return dockerCli.Initialize(opts) }, DisableFlagsInUseLine: true, } opts, flags = cli.SetupPluginRootCommand(cmd) cmd.SetOutput(dockerCli.Out()) cmd.AddCommand( plugin, newMetadataSubcommand(plugin, meta), ) cli.DisableFlagsInUseLine(cmd) return cmd } func newMetadataSubcommand(plugin *cobra.Command, meta manager.Metadata) *cobra.Command { if meta.ShortDescription == "" { meta.ShortDescription = plugin.Short } cmd := &cobra.Command{ Use: manager.MetadataSubcommandName, Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { enc := json.NewEncoder(os.Stdout) enc.SetEscapeHTML(false) enc.SetIndent("", " ") return enc.Encode(meta) }, } return cmd }