Skip to content

Commit

Permalink
add labels flag
Browse files Browse the repository at this point in the history
  • Loading branch information
femrtnz committed Sep 27, 2024
1 parent d23cbf4 commit 59e6faf
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 40 deletions.
6 changes: 3 additions & 3 deletions cmd/kubent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func main() {
log.Fatal().Err(err).Str("name", "Rego").Msg("Failed to filter results")
}

err = outputResults(results, config.Output, config.OutputFile)
err = outputResults(results, config.Output, config.OutputFile, config.Labels)
if err != nil {
log.Fatal().Err(err).Msgf("Failed to output results")
}
Expand All @@ -180,14 +180,14 @@ func configureGlobalLogging() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}

func outputResults(results []judge.Result, outputType string, outputFile string) error {
func outputResults(results []judge.Result, outputType string, outputFile string, labels bool) error {
printer, err := printer.NewPrinter(outputType, outputFile)
if err != nil {
return fmt.Errorf("failed to create printer: %v", err)
}
defer printer.Close()

err = printer.Print(results)
err = printer.Print(results, labels)
if err != nil {
return fmt.Errorf("failed to print results: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubent/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func Test_outputResults(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := outputResults(tt.args.results, tt.args.outputType, tt.args.outputFile); (err != nil) != tt.wantErr {
if err := outputResults(tt.args.results, tt.args.outputType, tt.args.outputFile, false); (err != nil) != tt.wantErr {
t.Errorf("unexpected error - got: %v, wantErr: %v", err, tt.wantErr)
}
})
Expand Down
62 changes: 43 additions & 19 deletions pkg/printer/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *csvPrinter) Close() error {
}

// Print will print results in CSV format
func (c *csvPrinter) Print(results []judge.Result) error {
func (c *csvPrinter) Print(results []judge.Result, labels bool) error {

sort.Slice(results, func(i, j int) bool {
return results[i].Name < results[j].Name
Expand All @@ -46,26 +46,50 @@ func (c *csvPrinter) Print(results []judge.Result) error {

w := csv.NewWriter(c.commonPrinter.outputFile)

w.Write([]string{
"api_version",
"kind",
"namespace",
"name",
"replace_with",
"since",
"rule_set",
})

for _, r := range results {
if labels {
w.Write([]string{
"api_version",
"kind",
"namespace",
"name",
"replace_with",
"since",
"rule_set",
"labels",
})
for _, r := range results {
w.Write([]string{
r.ApiVersion,
r.Kind,
r.Namespace,
r.Name,
r.ReplaceWith,
r.Since.String(),
r.RuleSet,
mapToCommaSeparatedString(r.Labels),
})
}
} else {
w.Write([]string{
r.ApiVersion,
r.Kind,
r.Namespace,
r.Name,
r.ReplaceWith,
r.Since.String(),
r.RuleSet,
"api_version",
"kind",
"namespace",
"name",
"replace_with",
"since",
"rule_set",
})
for _, r := range results {
w.Write([]string{
r.ApiVersion,
r.Kind,
r.Namespace,
r.Name,
r.ReplaceWith,
r.Since.String(),
r.RuleSet,
})
}
}

w.Flush()
Expand Down
35 changes: 34 additions & 1 deletion pkg/printer/csv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,40 @@ func TestCSVPrinterPrint(t *testing.T) {
Labels: map[string]interface{}{"app": "php-apache-app"},
}}

if err := tp.Print(results); err != nil {
if err := tp.Print(results, true); err != nil {
t.Fatalf("unexpected error: %v", err)
}

fi, _ := tmpFile.Stat()
if fi.Size() == 0 {
t.Fatalf("expected non-zero size output file: %v", err)
}
}

func TestCSVPrinterPrintNoLabels(t *testing.T) {
tmpFile, err := ioutil.TempFile(os.TempDir(), tempFilePrefix)
if err != nil {
t.Fatalf(tempFileCreateFailureMessage, err)
}
defer os.Remove(tmpFile.Name())

tp := &csvPrinter{
commonPrinter: &commonPrinter{tmpFile},
}

version, _ := judge.NewVersion("1.2.3")
results := []judge.Result{{
Name: "Name",
Namespace: "Namespace",
Kind: "Kind",
ApiVersion: "1.2.3",
RuleSet: "Test",
ReplaceWith: "4.5.6",
Since: version,
Labels: map[string]interface{}{},
}}

if err := tp.Print(results, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/printer/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (c *jsonPrinter) Close() error {
}

// Print will print results in text format
func (c *jsonPrinter) Print(results []judge.Result) error {
func (c *jsonPrinter) Print(results []judge.Result, labels bool) error {
writer := bufio.NewWriter(c.commonPrinter.outputFile)
defer writer.Flush()

Expand Down
44 changes: 43 additions & 1 deletion pkg/printer/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,49 @@ func Test_jsonPrinter_Print(t *testing.T) {
Labels: map[string]interface{}{"label1": "value1", "label2": "value2"},
}}

if err := c.Print(results); err != nil {
if err := c.Print(results, true); err != nil {
t.Fatalf("unexpected error: %v", err)
}

tmpFile.Seek(0, 0)

var readResults []judge.Result
readBytes, err := ioutil.ReadAll(tmpFile)
if err != nil {
t.Fatalf("unexpected error reading back the file: %v", err)
}
if err := json.Unmarshal(readBytes, &readResults); err != nil {
t.Fatalf("unexpected error unmarshalling the previously written file: %v", err)
}
if !reflect.DeepEqual(readResults, results) {
t.Fatalf("written and read result do not seem to be equal")
}
}

func Test_jsonPrinter_PrintNoLabel(t *testing.T) {
tmpFile, err := ioutil.TempFile(os.TempDir(), tempFilePrefix)
if err != nil {
t.Fatalf(tempFileCreateFailureMessage, err)
}
defer os.Remove(tmpFile.Name())

c := &jsonPrinter{
commonPrinter: &commonPrinter{tmpFile},
}

version, _ := judge.NewVersion("1.2.3")
results := []judge.Result{{
Name: "Name",
Namespace: "Namespace",
Kind: "Kind",
ApiVersion: "1.2.3",
RuleSet: "Test",
ReplaceWith: "4.5.6",
Since: version,
Labels: map[string]interface{}{},
}}

if err := c.Print(results, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var printers = map[string]func(string) (Printer, error){
}

type Printer interface {
Print([]judge.Result) error
Print([]judge.Result, bool) error
Close() error
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/printer/printer_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package printer

import (
"fmt"
"strings"
)

func mapToCommaSeparatedString(m map[string]interface{}) string {
var sb strings.Builder
for k, v := range m {
if sb.Len() > 0 {
sb.WriteString(", ")
}
sb.WriteString(fmt.Sprintf("%s:%v", k, v))
}
return sb.String()
}
36 changes: 36 additions & 0 deletions pkg/printer/printer_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package printer

import (
"testing"
)

func TestMapToCommaSeparatedString(t *testing.T) {
tests := []struct {
input map[string]interface{}
expected string
}{
{
input: map[string]interface{}{},
expected: "",
},
{
input: map[string]interface{}{"key1": "value1"},
expected: "key1:value1",
},
{
input: map[string]interface{}{"key1": "value1", "key2": "value2"},
expected: "key1:value1, key2:value2",
},
{
input: map[string]interface{}{"key1": 123, "key2": true, "key3": 45.67},
expected: "key1:123, key2:true, key3:45.67",
},
}

for _, test := range tests {
result := mapToCommaSeparatedString(test.input)
if result != test.expected {
t.Errorf("For input %v, expected %s but got %s", test.input, test.expected, result)
}
}
}
24 changes: 12 additions & 12 deletions pkg/printer/text.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (c *textPrinter) Close() error {
return c.commonPrinter.Close()
}

func (c *textPrinter) Print(results []judge.Result) error {
func (c *textPrinter) Print(results []judge.Result, labels bool) error {

sort.Slice(results, func(i, j int) bool {
return results[i].Name < results[j].Name
Expand All @@ -54,19 +54,19 @@ func (c *textPrinter) Print(results []judge.Result) error {
fmt.Fprintf(w, "%s\n", strings.Repeat("_", 90))
fmt.Fprintf(w, ">>> %s <<<\n", ruleSet)
fmt.Fprintf(w, "%s\n", strings.Repeat("-", 90))
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s) \t%s\n", "KIND", "NAMESPACE", "NAME", "API_VERSION", "REPLACE_WITH", "SINCE", "LABELS")
if labels {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s) \t%s\n", "KIND", "NAMESPACE", "NAME", "API_VERSION", "REPLACE_WITH", "SINCE", "LABELS")
} else {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s)\n", "KIND", "NAMESPACE", "NAME", "API_VERSION", "REPLACE_WITH", "SINCE")
}

}
if labels {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s) \t%s\n", r.Kind, r.Namespace, r.Name, r.ApiVersion, r.ReplaceWith, r.Since, mapToCommaSeparatedString(r.Labels))
} else {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s) \n", r.Kind, r.Namespace, r.Name, r.ApiVersion, r.ReplaceWith, r.Since)
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s \t(%s) \t%s\n", r.Kind, r.Namespace, r.Name, r.ApiVersion, r.ReplaceWith, r.Since, mapToCommaSeparatedString(r.Labels))
}
w.Flush()
return nil
}

// Helper function to convert labels map to comma-separated string
func mapToCommaSeparatedString(m map[string]interface{}) string {
var parts []string
for key, value := range m {
parts = append(parts, fmt.Sprintf("%s:%s", key, value))
}
return strings.Join(parts, ", ")
}
35 changes: 34 additions & 1 deletion pkg/printer/text_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,40 @@ func Test_textPrinter_Print(t *testing.T) {
Labels: map[string]interface{}{"label1": "value1", "label2": "value2"},
}}

if err := tp.Print(results); err != nil {
if err := tp.Print(results, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}

fi, _ := tmpFile.Stat()
if fi.Size() == 0 {
t.Fatalf("expected non-zero size output file: %v", err)
}
}

func Test_textPrinter_PrintNoLabel(t *testing.T) {
tmpFile, err := ioutil.TempFile(os.TempDir(), tempFilePrefix)
if err != nil {
t.Fatalf(tempFileCreateFailureMessage, err)
}
defer os.Remove(tmpFile.Name())

tp := &textPrinter{
commonPrinter: &commonPrinter{tmpFile},
}

version, _ := judge.NewVersion("1.2.3")
results := []judge.Result{{
Name: "Name",
Namespace: "Namespace",
Kind: "Kind",
ApiVersion: "1.2.3",
RuleSet: "Test",
ReplaceWith: "4.5.6",
Since: version,
Labels: map[string]interface{}{},
}}

if err := tp.Print(results, false); err != nil {
t.Fatalf("unexpected error: %v", err)
}

Expand Down

0 comments on commit 59e6faf

Please sign in to comment.