...
1
16
17 package genericclioptions
18
19 import (
20 "fmt"
21 "sort"
22 "strings"
23
24 "github.com/spf13/cobra"
25
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/cli-runtime/pkg/printers"
28 )
29
30
31
32 type NoCompatiblePrinterError struct {
33 OutputFormat *string
34 AllowedFormats []string
35 Options interface{}
36 }
37
38 func (e NoCompatiblePrinterError) Error() string {
39 output := ""
40 if e.OutputFormat != nil {
41 output = *e.OutputFormat
42 }
43
44 sort.Strings(e.AllowedFormats)
45 return fmt.Sprintf("unable to match a printer suitable for the output format %q, allowed formats are: %s", output, strings.Join(e.AllowedFormats, ","))
46 }
47
48
49
50 func IsNoCompatiblePrinterError(err error) bool {
51 if err == nil {
52 return false
53 }
54
55 _, ok := err.(NoCompatiblePrinterError)
56 return ok
57 }
58
59
60
61
62 type PrintFlags struct {
63 JSONYamlPrintFlags *JSONYamlPrintFlags
64 NamePrintFlags *NamePrintFlags
65 TemplatePrinterFlags *KubeTemplatePrintFlags
66
67 TypeSetterPrinter *printers.TypeSetterPrinter
68
69 OutputFormat *string
70
71
72
73 OutputFlagSpecified func() bool
74 }
75
76
77 func (f *PrintFlags) Complete(successTemplate string) error {
78 return f.NamePrintFlags.Complete(successTemplate)
79 }
80
81
82 func (f *PrintFlags) AllowedFormats() []string {
83 ret := []string{}
84 ret = append(ret, f.JSONYamlPrintFlags.AllowedFormats()...)
85 ret = append(ret, f.NamePrintFlags.AllowedFormats()...)
86 ret = append(ret, f.TemplatePrinterFlags.AllowedFormats()...)
87 return ret
88 }
89
90
91
92
93
94 func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
95 outputFormat := ""
96 if f.OutputFormat != nil {
97 outputFormat = *f.OutputFormat
98 }
99
100
101
102 templateFlagSpecified := f.TemplatePrinterFlags != nil &&
103 f.TemplatePrinterFlags.TemplateArgument != nil &&
104 len(*f.TemplatePrinterFlags.TemplateArgument) > 0
105 outputFlagSpecified := f.OutputFlagSpecified != nil && f.OutputFlagSpecified()
106 if templateFlagSpecified && !outputFlagSpecified {
107 outputFormat = "go-template"
108 }
109
110 if f.JSONYamlPrintFlags != nil {
111 if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
112 return f.TypeSetterPrinter.WrapToPrinter(p, err)
113 }
114 }
115
116 if f.NamePrintFlags != nil {
117 if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
118 return f.TypeSetterPrinter.WrapToPrinter(p, err)
119 }
120 }
121
122 if f.TemplatePrinterFlags != nil {
123 if p, err := f.TemplatePrinterFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
124 return f.TypeSetterPrinter.WrapToPrinter(p, err)
125 }
126 }
127
128 return nil, NoCompatiblePrinterError{OutputFormat: f.OutputFormat, AllowedFormats: f.AllowedFormats()}
129 }
130
131
132
133 func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
134 f.JSONYamlPrintFlags.AddFlags(cmd)
135 f.NamePrintFlags.AddFlags(cmd)
136 f.TemplatePrinterFlags.AddFlags(cmd)
137
138 if f.OutputFormat != nil {
139 cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, fmt.Sprintf(`Output format. One of: (%s).`, strings.Join(f.AllowedFormats(), ", ")))
140 if f.OutputFlagSpecified == nil {
141 f.OutputFlagSpecified = func() bool {
142 return cmd.Flag("output").Changed
143 }
144 }
145 }
146 }
147
148
149 func (f *PrintFlags) WithDefaultOutput(output string) *PrintFlags {
150 f.OutputFormat = &output
151 return f
152 }
153
154
155 func (f *PrintFlags) WithTypeSetter(scheme *runtime.Scheme) *PrintFlags {
156 f.TypeSetterPrinter = printers.NewTypeSetter(scheme)
157 return f
158 }
159
160
161 func NewPrintFlags(operation string) *PrintFlags {
162 outputFormat := ""
163
164 return &PrintFlags{
165 OutputFormat: &outputFormat,
166
167 JSONYamlPrintFlags: NewJSONYamlPrintFlags(),
168 NamePrintFlags: NewNamePrintFlags(operation),
169 TemplatePrinterFlags: NewKubeTemplatePrintFlags(),
170 }
171 }
172
View as plain text