diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/common/completion.go | 27 | ||||
-rw-r--r-- | cmd/podman/common/completion_test.go | 12 | ||||
-rw-r--r-- | cmd/podman/play/kube.go | 9 |
3 files changed, 33 insertions, 15 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 6149a4465..e07e28dab 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -992,13 +992,6 @@ func AutocompleteFormat(o interface{}) func(cmd *cobra.Command, args []string, t fields := strings.Split(field[len(field)-1], ".") f := reflect.ValueOf(o) for i := 1; i < len(fields); i++ { - val := getActualStructType(f) - if val == nil { - // no struct return nothing to complete - return nil, cobra.ShellCompDirectiveNoFileComp - } - f = *val - // last field get all names to suggest if i == len(fields)-1 { suggestions := getStructFields(f, fields[i]) @@ -1008,6 +1001,14 @@ func AutocompleteFormat(o interface{}) func(cmd *cobra.Command, args []string, t toComplete = strings.Join(toCompArr, ".") return prefixSlice(toComplete, suggestions), cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp } + + val := getActualStructType(f) + if val == nil { + // no struct return nothing to complete + return nil, cobra.ShellCompDirectiveNoFileComp + } + f = *val + // set the next struct field f = f.FieldByName(fields[i]) } @@ -1038,12 +1039,15 @@ func getActualStructType(f reflect.Value) *reflect.Value { // getStructFields reads all struct field names and method names and returns them. func getStructFields(f reflect.Value, prefix string) []string { - suggestions := []string{} + var suggestions []string + if f.IsValid() { + suggestions = append(suggestions, getMethodNames(f, prefix)...) + } val := getActualStructType(f) if val == nil { // no struct return nothing to complete - return nil + return suggestions } f = *val @@ -1069,7 +1073,11 @@ func getStructFields(f reflect.Value, prefix string) []string { suggestions = append(suggestions, fname+suffix) } } + return suggestions +} +func getMethodNames(f reflect.Value, prefix string) []string { + suggestions := make([]string, 0, f.NumMethod()) for j := 0; j < f.NumMethod(); j++ { fname := f.Type().Method(j).Name if strings.HasPrefix(fname, prefix) { @@ -1077,7 +1085,6 @@ func getStructFields(f reflect.Value, prefix string) []string { suggestions = append(suggestions, fname+"}}") } } - return suggestions } diff --git a/cmd/podman/common/completion_test.go b/cmd/podman/common/completion_test.go index ae117a173..13f45a662 100644 --- a/cmd/podman/common/completion_test.go +++ b/cmd/podman/common/completion_test.go @@ -25,7 +25,9 @@ func (c Car) Type() string { return "" } -func (c Car) Color() string { +// Note: It is important that this function is *Car and the Type one is just Car. +// The reflect logic behaves differently for these cases so we have to test both. +func (c *Car) Color() string { return "" } @@ -94,7 +96,7 @@ func TestAutocompleteFormat(t *testing.T) { { "second level struct field name", "{{ .Car.", - []string{"{{ .Car.Brand}}", "{{ .Car.Stats.", "{{ .Car.Extras}}", "{{ .Car.Color}}", "{{ .Car.Type}}"}, + []string{"{{ .Car.Color}}", "{{ .Car.Type}}", "{{ .Car.Brand}}", "{{ .Car.Stats.", "{{ .Car.Extras}}"}, }, { "second level struct field name", @@ -104,7 +106,7 @@ func TestAutocompleteFormat(t *testing.T) { { "second level nil struct field name", "{{ .Car2.", - []string{"{{ .Car2.Brand}}", "{{ .Car2.Stats.", "{{ .Car2.Extras}}", "{{ .Car2.Color}}", "{{ .Car2.Type}}"}, + []string{"{{ .Car2.Color}}", "{{ .Car2.Type}}", "{{ .Car2.Brand}}", "{{ .Car2.Stats.", "{{ .Car2.Extras}}"}, }, { "three level struct field name", @@ -134,8 +136,8 @@ func TestAutocompleteFormat(t *testing.T) { { "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}}"}, + []string{"{{ .Car.Brand }} {{ .Car.Color}}", "{{ .Car.Brand }} {{ .Car.Type}}", "{{ .Car.Brand }} {{ .Car.Brand}}", + "{{ .Car.Brand }} {{ .Car.Stats.", "{{ .Car.Brand }} {{ .Car.Extras}}"}, }, { "only dot without variable", diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go index 5fe059139..f5b121009 100644 --- a/cmd/podman/play/kube.go +++ b/cmd/podman/play/kube.go @@ -139,6 +139,15 @@ func init() { flags.StringVar(&kubeOptions.ContextDir, contextDirFlagName, "", "Path to top level of context directory") _ = kubeCmd.RegisterFlagCompletionFunc(contextDirFlagName, completion.AutocompleteDefault) + // NOTE: The service-container flag is marked as hidden as it + // is purely designed for running play-kube in systemd units. + // It is not something users should need to know or care about. + // + // Having a flag rather than an env variable is cleaner. + serviceFlagName := "service-container" + flags.BoolVar(&kubeOptions.ServiceContainer, serviceFlagName, false, "Starts a service container before all pods") + _ = flags.MarkHidden("service-container") + flags.StringVar(&kubeOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") _ = flags.MarkHidden("signature-policy") |