Skip to content

Commit 65dc03a

Browse files
authored
Merge pull request #2139 from palnabarun/kepctl-query-outputs
Add YAML and JSON printers to kepctl query
2 parents 0c170aa + 6090c9c commit 65dc03a

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

cmd/kepctl/query.go

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"fmt"
21+
2022
"github.com/spf13/cobra"
2123

2224
"k8s.io/enhancements/pkg/kepctl"
@@ -43,6 +45,7 @@ func buildQueryCommand(k *kepctl.Client) *cobra.Command {
4345
f.StringSliceVar(&opts.Stage, "stage", nil, "Stage")
4446
f.StringSliceVar(&opts.PRRApprover, "prr", nil, "Prod Readiness Approver")
4547
f.BoolVar(&opts.IncludePRs, "include-prs", false, "Include PRs in the results")
48+
f.StringVar(&opts.Output, "output", kepctl.DefaultOutputOpt, fmt.Sprintf("Output format. Can be %v", kepctl.SupportedOutputOpts))
4649

4750
addRepoPathFlag(f, &opts.CommonArgs)
4851

pkg/kepctl/kepctl.go

+23
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package kepctl
1919
import (
2020
"bytes"
2121
"context"
22+
"encoding/json"
2223
"fmt"
2324
"io"
2425
"io/ioutil"
@@ -481,3 +482,25 @@ func (c *Client) PrintTable(configs []PrintConfig, proposals []*keps.Proposal) {
481482
}
482483
table.Render()
483484
}
485+
486+
// PrintYAML outputs keps array as YAML to c.Out
487+
func (c *Client) PrintYAML(proposals []*keps.Proposal) {
488+
data, err := yaml.Marshal(proposals)
489+
if err != nil {
490+
fmt.Fprintf(c.Err, "error printing keps as YAML: %s", err)
491+
return
492+
}
493+
494+
fmt.Fprintln(c.Out, string(data))
495+
}
496+
497+
// PrintJSON outputs keps array as YAML to c.Out
498+
func (c *Client) PrintJSON(proposals []*keps.Proposal) {
499+
data, err := json.Marshal(proposals)
500+
if err != nil {
501+
fmt.Fprintf(c.Err, "error printing keps as JSON: %s", err)
502+
return
503+
}
504+
505+
fmt.Fprintln(c.Out, string(data))
506+
}

pkg/kepctl/query.go

+60-2
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,31 @@ import (
2626
"k8s.io/enhancements/pkg/kepval/keps/validations"
2727
)
2828

29+
var (
30+
// SupportedOutputOpts stores all allowed query output formats
31+
SupportedOutputOpts = []string{
32+
"table",
33+
"json",
34+
"yaml",
35+
}
36+
37+
// DefaultOutputOpt is the default output format for kepctl query
38+
DefaultOutputOpt = "table"
39+
40+
StructuredOutputFormats = []string{
41+
"json",
42+
"yaml",
43+
}
44+
)
45+
2946
type QueryOpts struct {
3047
CommonArgs
3148
SIG []string
3249
Status []string
3350
Stage []string
3451
PRRApprover []string
3552
IncludePRs bool
53+
Output string
3654
}
3755

3856
// Validate checks the args and cleans them up if needed
@@ -47,14 +65,33 @@ func (c *QueryOpts) Validate(args []string) error {
4765
}
4866
c.SIG = sigs
4967
}
68+
69+
// check if the Output specified is one of "", "json" or "yaml"
70+
if !sliceContains(SupportedOutputOpts, c.Output) {
71+
return fmt.Errorf("unsupported output format: %s. Valid values: %v", c.Output, SupportedOutputOpts)
72+
}
73+
5074
//TODO: check the valid values of stage, status, etc.
5175
return nil
5276
}
5377

5478
// Query searches the local repo and possibly GitHub for KEPs
5579
// that match the search criteria.
5680
func (c *Client) Query(opts QueryOpts) error {
57-
fmt.Fprintf(c.Out, "Searching for KEPs...\n")
81+
// if output format is json/yaml, suppress other outputs
82+
// json/yaml are structured formats, logging events which
83+
// do not conform to the spec will create formatting issues
84+
var suppressOutputs bool
85+
if sliceContains(StructuredOutputFormats, opts.Output) {
86+
suppressOutputs = true
87+
} else {
88+
suppressOutputs = false
89+
}
90+
91+
if !suppressOutputs {
92+
fmt.Fprintf(c.Out, "Searching for KEPs...\n")
93+
}
94+
5895
repoPath, err := c.findEnhancementsRepo(opts.CommonArgs)
5996
if err != nil {
6097
return errors.Wrap(err, "unable to search KEPs")
@@ -99,7 +136,18 @@ func (c *Client) Query(opts QueryOpts) error {
99136
keep = append(keep, k)
100137
}
101138

102-
c.PrintTable(DefaultPrintConfigs("LastUpdated", "Stage", "Status", "SIG", "Authors", "Title", "Link"), keep)
139+
switch opts.Output {
140+
case "table":
141+
c.PrintTable(DefaultPrintConfigs("LastUpdated", "Stage", "Status", "SIG", "Authors", "Title", "Link"), keep)
142+
case "yaml":
143+
c.PrintYAML(keep)
144+
case "json":
145+
c.PrintJSON(keep)
146+
default:
147+
// this check happens as a validation step in cobra as well
148+
// added it for additional verbosity
149+
return fmt.Errorf("unsupported output format: %s. Valid values: %s", opts.Output, SupportedOutputOpts)
150+
}
103151
return nil
104152
}
105153

@@ -111,6 +159,16 @@ func sliceToMap(s []string) map[string]bool {
111159
return m
112160
}
113161

162+
func sliceContains(s []string, e string) bool {
163+
for _, k := range s {
164+
if k == e {
165+
return true
166+
}
167+
}
168+
169+
return false
170+
}
171+
114172
// returns all strings in vals that match at least one
115173
// regexp in regexps
116174
func selectByRegexp(vals []string, regexps []string) ([]string, error) {

0 commit comments

Comments
 (0)