Add go template shell completion for --format

The --format flags accepts go template strings. I use this often but I
consistently forget the field names. This commit adds a way to provide
shell completion for the --format flag. It works by automatically
receiving the field names with the reflect package from the given
struct. This requires almost no maintenance since this ensures that we
always use the correct field names. This also works for nested structs.

```
$ podman ps --format "{{.P"
{{.Pid}}      {{.PIDNS}}    {{.Pod}}      {{.PodName}}  {{.Ports}}
```

NOTE: This only works when you use quotes otherwise the shell does not
provide completions. Also this does not work for fish at the moment.

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
This commit is contained in:
Paul Holzinger 2021-04-21 11:32:03 +02:00
parent 979f047d73
commit d81021ed26
27 changed files with 258 additions and 28 deletions

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
"reflect"
"strings" "strings"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
@ -891,10 +892,85 @@ func AutocompleteNetworkFlag(cmd *cobra.Command, args []string, toComplete strin
return append(networks, suggestions...), dir return append(networks, suggestions...), dir
} }
// AutocompleteJSONFormat - Autocomplete format flag option. // AutocompleteFormat - Autocomplete json or a given struct to use for a go template.
// -> "json" // The input can be nil, In this case only json will be autocompleted.
func AutocompleteJSONFormat(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { // This function will only work for structs other types are not supported.
return []string{"json"}, cobra.ShellCompDirectiveNoFileComp // When "{{." is typed the field and method names of the given struct will be completed.
// This also works recursive for nested structs.
func AutocompleteFormat(o interface{}) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// this function provides shell completion for go templates
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// autocomplete json when nothing or json is typed
if strings.HasPrefix("json", toComplete) {
return []string{"json"}, cobra.ShellCompDirectiveNoFileComp
}
// no input struct we cannot provide completion return nothing
if o == nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
// toComplete could look like this: {{ .Config }} {{ .Field.F
// 1. split the template variable delimiter
vars := strings.Split(toComplete, "{{")
if len(vars) == 1 {
// no variables return no completion
return nil, cobra.ShellCompDirectiveNoFileComp
}
// clean the spaces from the last var
field := strings.Split(vars[len(vars)-1], " ")
// split this into it struct field names
fields := strings.Split(field[len(field)-1], ".")
f := reflect.ValueOf(o)
for i := 1; i < len(fields); i++ {
if f.Kind() == reflect.Ptr {
f = f.Elem()
}
// // the only supported type is struct
if f.Kind() != reflect.Struct {
return nil, cobra.ShellCompDirectiveNoFileComp
}
// last field get all names to suggest
if i == len(fields)-1 {
suggestions := []string{}
for j := 0; j < f.NumField(); j++ {
fname := f.Type().Field(j).Name
suffix := "}}"
kind := f.Type().Field(j).Type.Kind()
if kind == reflect.Ptr {
// make sure to read the actual type when it is a pointer
kind = f.Type().Field(j).Type.Elem().Kind()
}
// when we have a nested struct do not append braces instead append a dot
if kind == reflect.Struct {
suffix = "."
}
if strings.HasPrefix(fname, fields[i]) {
// add field name with closing braces
suggestions = append(suggestions, fname+suffix)
}
}
for j := 0; j < f.NumMethod(); j++ {
fname := f.Type().Method(j).Name
if strings.HasPrefix(fname, fields[i]) {
// add method name with closing braces
suggestions = append(suggestions, fname+"}}")
}
}
// add the current toComplete value in front so that the shell can complete this correctly
toCompArr := strings.Split(toComplete, ".")
toCompArr[len(toCompArr)-1] = ""
toComplete = strings.Join(toCompArr, ".")
return prefixSlice(toComplete, suggestions), cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
}
// set the next struct field
f = f.FieldByName(fields[i])
}
return nil, cobra.ShellCompDirectiveNoFileComp
}
} }
// AutocompleteEventFilter - Autocomplete event filter flag options. // AutocompleteEventFilter - Autocomplete event filter flag options.

View File

@ -0,0 +1,142 @@
package common_test
import (
"testing"
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
type Car struct {
Brand string
Stats struct {
HP *int
Displacement int
}
Extras map[string]string
}
func (c Car) Type() string {
return ""
}
func (c Car) Color() string {
return ""
}
func TestAutocompleteFormat(t *testing.T) {
testStruct := struct {
Name string
Age int
Car *Car
}{}
testStruct.Car = &Car{}
testStruct.Car.Extras = map[string]string{"test": "1"}
tests := []struct {
name string
toComplete string
expected []string
}{
{
"empty completion",
"",
[]string{"json"},
},
{
"json completion",
"json",
[]string{"json"},
},
{
"invalid completion",
"blahblah",
nil,
},
{
"invalid completion",
"{{",
nil,
},
{
"invalid completion",
"{{ ",
nil,
},
{
"invalid completion",
"{{ ..",
nil,
},
{
"fist level struct field name",
"{{.",
[]string{"{{.Name}}", "{{.Age}}", "{{.Car."},
},
{
"fist level struct field name",
"{{ .",
[]string{"{{ .Name}}", "{{ .Age}}", "{{ .Car."},
},
{
"fist level struct field name",
"{{ .N",
[]string{"{{ .Name}}"},
},
{
"second level struct field name",
"{{ .Car.",
[]string{"{{ .Car.Brand}}", "{{ .Car.Stats.", "{{ .Car.Extras}}", "{{ .Car.Color}}", "{{ .Car.Type}}"},
},
{
"second level struct field name",
"{{ .Car.B",
[]string{"{{ .Car.Brand}}"},
},
{
"three level struct field name",
"{{ .Car.Stats.",
[]string{"{{ .Car.Stats.HP}}", "{{ .Car.Stats.Displacement}}"},
},
{
"three level struct field name",
"{{ .Car.Stats.D",
[]string{"{{ .Car.Stats.Displacement}}"},
},
{
"second level struct field name",
"{{ .Car.B",
[]string{"{{ .Car.Brand}}"},
},
{
"invalid field name",
"{{ .Ca.B",
nil,
},
{
"map key names don't work",
"{{ .Car.Extras.",
nil,
},
{
"two variables struct field name",
"{{ .Car.Brand }} {{ .Car.",
[]string{"{{ .Car.Brand }} {{ .Car.Brand}}", "{{ .Car.Brand }} {{ .Car.Stats.", "{{ .Car.Brand }} {{ .Car.Extras}}",
"{{ .Car.Brand }} {{ .Car.Color}}", "{{ .Car.Brand }} {{ .Car.Type}}"},
},
{
"only dot without variable",
".",
nil,
},
}
for _, test := range tests {
completion, directive := common.AutocompleteFormat(testStruct)(nil, nil, test.toComplete)
// directive should always be greater than ShellCompDirectiveNoFileComp
assert.GreaterOrEqual(t, directive, cobra.ShellCompDirectiveNoFileComp, "unexpected ShellCompDirective")
assert.Equal(t, test.expected, completion, test.name)
}
}

View File

@ -39,7 +39,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format") flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format")
_ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
validate.AddLatestFlag(diffCmd, &diffOpts.Latest) validate.AddLatestFlag(diffCmd, &diffOpts.Latest)
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/inspect" "github.com/containers/podman/v3/cmd/podman/inspect"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -35,7 +36,12 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json")
_ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectContainerData{
State: &define.InspectContainerState{},
NetworkSettings: &define.InspectNetworkSettings{},
Config: &define.InspectContainerConfig{},
HostConfig: &define.InspectContainerHostConfig{},
}))
validate.AddLatestFlag(inspectCmd, &inspectOpts.Latest) validate.AddLatestFlag(inspectCmd, &inspectOpts.Latest)
} }

View File

@ -61,7 +61,7 @@ func mountFlags(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&mountOpts.Format, formatFlagName, "", "Print the mounted containers in specified format (json)") flags.StringVar(&mountOpts.Format, formatFlagName, "", "Print the mounted containers in specified format (json)")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
flags.BoolVar(&mountOpts.NoTruncate, "notruncate", false, "Do not truncate output") flags.BoolVar(&mountOpts.NoTruncate, "notruncate", false, "Do not truncate output")
} }

View File

@ -87,7 +87,7 @@ func listFlagSet(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&listOpts.Format, formatFlagName, "", "Pretty-print containers to JSON or using a Go template") flags.StringVar(&listOpts.Format, formatFlagName, "", "Pretty-print containers to JSON or using a Go template")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ListContainer{}))
lastFlagName := "last" lastFlagName := "last"
flags.IntVarP(&listOpts.Last, lastFlagName, "n", -1, "Print the n last created containers (all states)") flags.IntVarP(&listOpts.Last, lastFlagName, "n", -1, "Print the n last created containers (all states)")

View File

@ -71,7 +71,7 @@ func statFlags(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template") flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.ContainerStats{}))
flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen between intervals") flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen between intervals")
flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false") flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false")

View File

@ -43,7 +43,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format") flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format")
_ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
validate.AddLatestFlag(diffCmd, &diffOpts.Latest) validate.AddLatestFlag(diffCmd, &diffOpts.Latest)
} }

View File

@ -72,7 +72,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)") flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
flags.SetNormalizeFunc(utils.AliasFlags) flags.SetNormalizeFunc(utils.AliasFlags)
} }

View File

@ -41,7 +41,7 @@ func diffFlags(flags *pflag.FlagSet) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format") flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format")
_ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
} }
func diff(cmd *cobra.Command, args []string) error { func diff(cmd *cobra.Command, args []string) error {

View File

@ -74,7 +74,7 @@ func historyFlags(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&opts.format, formatFlagName, "", "Change the output to JSON or a Go template") flags.StringVar(&opts.format, formatFlagName, "", "Change the output to JSON or a Go template")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ImageHistoryLayer{}))
flags.BoolVarP(&opts.human, "human", "H", true, "Display sizes and dates in human readable format") flags.BoolVarP(&opts.human, "human", "H", true, "Display sizes and dates in human readable format")
flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate the output") flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate the output")

View File

@ -5,6 +5,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/inspect" "github.com/containers/podman/v3/cmd/podman/inspect"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
inspectTypes "github.com/containers/podman/v3/pkg/inspect"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -34,7 +35,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json")
_ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(inspectTypes.ImageData{}))
} }
func inspectExec(cmd *cobra.Command, args []string) error { func inspectExec(cmd *cobra.Command, args []string) error {

View File

@ -83,7 +83,7 @@ func imageListFlagSet(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&listFlag.format, formatFlagName, "", "Change the output format to JSON or a Go template") flags.StringVar(&listFlag.format, formatFlagName, "", "Change the output format to JSON or a Go template")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ImageSummary{}))
flags.BoolVar(&listFlag.digests, "digests", false, "Show digests") flags.BoolVar(&listFlag.digests, "digests", false, "Show digests")
flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print column headings") flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print column headings")

View File

@ -51,7 +51,7 @@ func mountFlags(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&mountOpts.Format, formatFlagName, "", "Print the mounted images in specified format (json)") flags.StringVar(&mountOpts.Format, formatFlagName, "", "Print the mounted images in specified format (json)")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
} }
func init() { func init() {

View File

@ -33,7 +33,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "", "Pretty-print network to JSON or using a Go template") flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "", "Pretty-print network to JSON or using a Go template")
_ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
} }
func networkInspect(_ *cobra.Command, args []string) error { func networkInspect(_ *cobra.Command, args []string) error {

View File

@ -41,7 +41,7 @@ var (
func networkListFlags(flags *pflag.FlagSet) { func networkListFlags(flags *pflag.FlagSet) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&networkListOptions.Format, formatFlagName, "", "Pretty-print networks to JSON or using a Go template") flags.StringVar(&networkListOptions.Format, formatFlagName, "", "Pretty-print networks to JSON or using a Go template")
_ = networklistCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = networklistCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPrintReports{}))
flags.BoolVarP(&networkListOptions.Quiet, "quiet", "q", false, "display only names") flags.BoolVarP(&networkListOptions.Quiet, "quiet", "q", false, "display only names")
flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate the network ID") flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate the network ID")

View File

@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -44,7 +45,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inspectOptions.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") flags.StringVarP(&inspectOptions.Format, formatFlagName, "f", "json", "Format the output to a Go template or json")
_ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectPodData{}))
validate.AddLatestFlag(inspectCmd, &inspectOptions.Latest) validate.AddLatestFlag(inspectCmd, &inspectOptions.Latest)
} }

View File

@ -61,7 +61,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&psInput.Format, formatFlagName, "", "Pretty-print pods to JSON or using a Go template") flags.StringVar(&psInput.Format, formatFlagName, "", "Pretty-print pods to JSON or using a Go template")
_ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPodReporter{}))
flags.Bool("noheading", false, "Do not print headers") flags.Bool("noheading", false, "Do not print headers")
flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod") flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod")

View File

@ -58,7 +58,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template") flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template")
_ = statsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = statsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.PodStatsReport{}))
flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen when streaming") flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen when streaming")
flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result") flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result")

View File

@ -40,7 +40,7 @@ func init() {
flags := inspectCmd.Flags() flags := inspectCmd.Flags()
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&format, formatFlagName, "", "Format volume output using Go template") flags.StringVar(&format, formatFlagName, "", "Format volume output using Go template")
_ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SecretInfoReport{}))
} }
func inspect(cmd *cobra.Command, args []string) error { func inspect(cmd *cobra.Command, args []string) error {

View File

@ -47,7 +47,7 @@ func init() {
flags := lsCmd.Flags() flags := lsCmd.Flags()
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&listFlag.format, formatFlagName, "{{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.CreatedAt}}\t{{.UpdatedAt}}\t\n", "Format volume output using Go template") flags.StringVar(&listFlag.format, formatFlagName, "{{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.CreatedAt}}\t{{.UpdatedAt}}\t\n", "Format volume output using Go template")
_ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SecretInfoReport{}))
flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers") flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers")
} }

View File

@ -52,7 +52,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&eventFormat, formatFlagName, "", "format the output using a Go template") flags.StringVar(&eventFormat, formatFlagName, "", "format the output using a Go template")
_ = eventsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = eventsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(events.Event{}))
flags.BoolVar(&eventOptions.Stream, "stream", true, "stream new events; for testing only") flags.BoolVar(&eventOptions.Stream, "stream", true, "stream new events; for testing only")

View File

@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -68,7 +69,7 @@ func infoFlags(cmd *cobra.Command) {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template")
_ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.Info{Host: &define.HostInfo{}, Store: &define.StoreInfo{}}))
} }
func info(cmd *cobra.Command, args []string) error { func info(cmd *cobra.Command, args []string) error {

View File

@ -38,7 +38,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&versionFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") flags.StringVarP(&versionFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template")
_ = versionCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = versionCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SystemVersionReport{}))
} }
func version(cmd *cobra.Command, args []string) error { func version(cmd *cobra.Command, args []string) error {

View File

@ -4,6 +4,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/inspect" "github.com/containers/podman/v3/cmd/podman/inspect"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -41,7 +42,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format volume output using Go template") flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format volume output using Go template")
_ = inspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = inspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectVolumeData{}))
} }
func volumeInspect(cmd *cobra.Command, args []string) error { func volumeInspect(cmd *cobra.Command, args []string) error {

View File

@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/parse" "github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -60,7 +61,7 @@ func init() {
formatFlagName := "format" formatFlagName := "format"
flags.StringVar(&cliOpts.Format, formatFlagName, "{{.Driver}}\t{{.Name}}\n", "Format volume output using Go template") flags.StringVar(&cliOpts.Format, formatFlagName, "{{.Driver}}\t{{.Name}}\n", "Format volume output using Go template")
_ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteJSONFormat) _ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectVolumeData{}))
flags.Bool("noheading", false, "Do not print headers") flags.Bool("noheading", false, "Do not print headers")
flags.BoolVarP(&cliOpts.Quiet, "quiet", "q", false, "Print volume output in quiet mode") flags.BoolVarP(&cliOpts.Quiet, "quiet", "q", false, "Print volume output in quiet mode")

1
go.sum
View File

@ -213,6 +213,7 @@ github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3E
github.com/containers/storage v1.24.8/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ= github.com/containers/storage v1.24.8/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ=
github.com/containers/storage v1.28.0/go.mod h1:ixAwO7Bj31cigqPEG7aCz+PYmxkDxbIFdUFioYdxbzI= github.com/containers/storage v1.28.0/go.mod h1:ixAwO7Bj31cigqPEG7aCz+PYmxkDxbIFdUFioYdxbzI=
github.com/containers/storage v1.28.1/go.mod h1:5bwiMh2LkrN3AWIfDFMH7A/xbVNLcve+oeXYvHvW8cc= github.com/containers/storage v1.28.1/go.mod h1:5bwiMh2LkrN3AWIfDFMH7A/xbVNLcve+oeXYvHvW8cc=
github.com/containers/storage v1.29.0/go.mod h1:u84RU4CCufGeJBNTRNwMB+FoE+AiFeFw4SsMoqAOeCM=
github.com/containers/storage v1.30.0 h1:KS6zmoPyy0Qcx1HCCiseQ0ysSckRvtiuoVpIGh9iwQA= github.com/containers/storage v1.30.0 h1:KS6zmoPyy0Qcx1HCCiseQ0ysSckRvtiuoVpIGh9iwQA=
github.com/containers/storage v1.30.0/go.mod h1:M/xn0pg6ReYFrLtWl5YELI/a4Xjq+Z3e5GJxQrJCcDI= github.com/containers/storage v1.30.0/go.mod h1:M/xn0pg6ReYFrLtWl5YELI/a4Xjq+Z3e5GJxQrJCcDI=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=