Skip to content

Commit c1f850f

Browse files
committed
fix: add output flag
1 parent 4764f5f commit c1f850f

File tree

5 files changed

+60
-36
lines changed

5 files changed

+60
-36
lines changed

Diff for: cmd/root.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ func init() {
4343
rootCmd.AddCommand(optimizeCmd)
4444

4545
optimizeCmd.PersistentFlags().String("preferences", "", "Path to preferences file (yaml)")
46-
optimizeCmd.PersistentFlags().Bool("non-interactive-view", false, "Show optimization results in non-interactive mode")
47-
optimizeCmd.PersistentFlags().Bool("csv-export", false, "Get CSV export")
48-
optimizeCmd.PersistentFlags().Bool("json-export", false, "Get json export")
46+
optimizeCmd.PersistentFlags().String("output", "interactive", "Show optimization results in selected output (possible values: interactive, table, csv, json. default value: interactive)")
4947
optimizeCmd.PersistentFlags().Bool("plugin-debug-mode", false, "Enable plugin debug mode (manager wont start plugin)")
5048
}
5149

@@ -99,12 +97,19 @@ func Execute() {
9997
return err
10098
}
10199

102-
nonInteractiveFlag := utils.ReadBooleanFlag(c, "non-interactive-view")
103-
csvExportFlag := utils.ReadBooleanFlag(c, "csv-export")
104-
jsonExportFlag := utils.ReadBooleanFlag(c, "json-export")
100+
nonInteractiveFlag := utils.ReadStringFlag(c, "output")
105101
manager := plugin2.New()
106102

107-
if nonInteractiveFlag || csvExportFlag || jsonExportFlag {
103+
switch nonInteractiveFlag {
104+
case "interactive":
105+
case "table":
106+
case "csv":
107+
case "json":
108+
default:
109+
return fmt.Errorf("output mode not recognized\npossible values: interactive, table, csv, json. default value: interactive (default \"interactive\")")
110+
}
111+
112+
if nonInteractiveFlag != "interactive" {
108113
manager.SetNonInteractiveView()
109114
}
110115

@@ -208,8 +213,8 @@ func Execute() {
208213
return err
209214
}
210215

211-
if nonInteractiveFlag || csvExportFlag || jsonExportFlag {
212-
err := manager.NonInteractiveView.WaitAndShowResults(nonInteractiveFlag, csvExportFlag, jsonExportFlag)
216+
if nonInteractiveFlag != "interactive" {
217+
err := manager.NonInteractiveView.WaitAndShowResults(nonInteractiveFlag)
213218
return err
214219
} else {
215220
helpController := controller.NewHelp()

Diff for: pkg/utils/view.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package utils
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
"strings"
6+
)
47

58
func PFloat64ToString(v *float64) string {
69
if v == nil {
@@ -76,3 +79,19 @@ func SizeByteToGB(v *int32) string {
7679
vv := *v // / 1000000000
7780
return fmt.Sprintf("%d GB", vv)
7881
}
82+
83+
func FormatFloat(number float64) string {
84+
parts := strings.Split(fmt.Sprintf("%.2f", number), ".")
85+
integerPart := parts[0]
86+
decimalPart := parts[1]
87+
88+
var result []rune
89+
for i, digit := range integerPart {
90+
if i > 0 && (len(integerPart)-i)%3 == 0 {
91+
result = append(result, ',')
92+
}
93+
result = append(result, rune(digit))
94+
}
95+
96+
return fmt.Sprintf("%s.%s", string(result), decimalPart)
97+
}

Diff for: view/non_interactive_view.go

+19-21
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/jedib0t/go-pretty/v6/table"
99
"github.com/jedib0t/go-pretty/v6/text"
1010
"github.com/kaytu-io/kaytu/pkg/plugin/proto/src/golang"
11+
"github.com/kaytu-io/kaytu/pkg/utils"
1112
"os"
1213
"sync"
1314
"time"
@@ -122,7 +123,7 @@ func getItemString(item *golang.OptimizationItem) string {
122123
totalSaving += dev.CurrentCost - dev.RightSizedCost
123124
}
124125
}
125-
row = append(row, item.Id, item.ResourceType, item.Region, item.Platform, fmt.Sprintf("$%.2f", totalSaving))
126+
row = append(row, item.Id, item.ResourceType, item.Region, item.Platform, fmt.Sprintf("$%s", utils.FormatFloat(totalSaving)))
126127
t.AppendRow(row)
127128
itemString += t.Render()
128129
itemString += "\n " + bold.Sprint("Devices") + ":"
@@ -196,7 +197,7 @@ func getDeviceString(dev *golang.Device) string {
196197
t.AppendHeader(headers)
197198
var row table.Row
198199
var itemString string
199-
row = append(row, "└─ "+dev.DeviceId, dev.ResourceType, dev.Runtime, dev.CurrentCost, dev.RightSizedCost, fmt.Sprintf("$%.2f", dev.CurrentCost-dev.RightSizedCost))
200+
row = append(row, "└─ "+dev.DeviceId, dev.ResourceType, dev.Runtime, dev.CurrentCost, dev.RightSizedCost, fmt.Sprintf("$%s", utils.FormatFloat(dev.CurrentCost-dev.RightSizedCost)))
200201
t.AppendRow(row)
201202
itemString += t.Render()
202203
itemString += "\n " + bold.Sprint("Properties") + ":\n" + getPropertiesString(dev.Properties)
@@ -281,29 +282,25 @@ func (v *NonInteractiveView) PublishResultsReady(ready *golang.ResultsReady) {
281282
v.resultsReady <- ready.Ready
282283
}
283284

284-
func (v *NonInteractiveView) WaitAndShowResults(showResults bool, csvExport bool, jsonExport bool) error {
285+
func (v *NonInteractiveView) WaitAndShowResults(nonInteractiveFlag string) error {
285286
go v.WaitForAllItems()
286287
go v.WaitForJobs()
287288
for {
288289
select {
289290
case ready := <-v.resultsReady:
290291
if ready == true {
291-
if showResults {
292+
if nonInteractiveFlag == "table" {
292293
str, err := v.OptimizationsString()
293294
if err != nil {
294295
return err
295296
}
296-
os.Stderr.WriteString(str)
297-
}
298-
if csvExport {
297+
os.Stdout.WriteString(str)
298+
} else if nonInteractiveFlag == "csv" {
299299
csvHeaders, csvRows := exportCsv(v.items)
300-
file, err := os.Create("export.csv")
301-
if err != nil {
302-
return err
303-
}
304-
writer := csv.NewWriter(file)
300+
out := os.Stdout
301+
writer := csv.NewWriter(out)
305302

306-
err = writer.Write(csvHeaders)
303+
err := writer.Write(csvHeaders)
307304
if err != nil {
308305
return err
309306
}
@@ -315,12 +312,11 @@ func (v *NonInteractiveView) WaitAndShowResults(showResults bool, csvExport bool
315312
}
316313
}
317314
writer.Flush()
318-
err = file.Close()
315+
err = out.Close()
319316
if err != nil {
320317
return err
321318
}
322-
}
323-
if jsonExport {
319+
} else if nonInteractiveFlag == "json" {
324320
jsonValue := struct {
325321
Items []*golang.OptimizationItem
326322
}{
@@ -331,19 +327,21 @@ func (v *NonInteractiveView) WaitAndShowResults(showResults bool, csvExport bool
331327
return err
332328
}
333329

334-
file, err := os.Create("export.json")
330+
out := os.Stdout
335331
if err != nil {
336332
return err
337333
}
338334

339-
_, err = file.Write(jsonData)
335+
_, err = out.Write(jsonData)
340336
if err != nil {
341337
return err
342338
}
343-
err = file.Close()
339+
err = out.Close()
344340
if err != nil {
345341
return err
346342
}
343+
} else {
344+
os.Stderr.WriteString("output mode not recognized!")
347345
}
348346
return nil
349347
}
@@ -427,8 +425,8 @@ func exportCsv(items []*golang.OptimizationItem) ([]string, [][]string) {
427425
for _, d := range i.Devices {
428426
for _, p := range d.Properties {
429427
rows = append(rows, []string{
430-
i.Id, i.ResourceType, i.Region, i.Platform, fmt.Sprintf("$%.2f", totalSaving),
431-
d.DeviceId, d.ResourceType, d.Runtime, fmt.Sprintf("$%.2f", d.CurrentCost), fmt.Sprintf("$%.2f", d.RightSizedCost), fmt.Sprintf("$%.2f", d.CurrentCost-d.RightSizedCost),
428+
i.Id, i.ResourceType, i.Region, i.Platform, fmt.Sprintf("$%s", utils.FormatFloat(totalSaving)),
429+
d.DeviceId, d.ResourceType, d.Runtime, fmt.Sprintf("$%s", utils.FormatFloat(d.CurrentCost)), fmt.Sprintf("$%s", utils.FormatFloat(d.RightSizedCost)), fmt.Sprintf("$%s", utils.FormatFloat(d.CurrentCost-d.RightSizedCost)),
432430
p.Key, p.Current, p.Average, p.Max, p.Recommended,
433431
})
434432
}

Diff for: view/page_optimization.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/evertras/bubble-table/table"
77
"github.com/kaytu-io/kaytu/controller"
88
"github.com/kaytu-io/kaytu/pkg/style"
9+
"github.com/kaytu-io/kaytu/pkg/utils"
910
"github.com/kaytu-io/kaytu/view/responsive"
1011
)
1112

@@ -90,7 +91,7 @@ func (m OptimizationsPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
9091
i.ResourceType,
9192
i.Region,
9293
i.Platform,
93-
fmt.Sprintf("$%.2f (%%%.2f)", totalSaving, (totalSaving/totalCurrentCost)*100),
94+
fmt.Sprintf("$%s (%%%.2f)", utils.FormatFloat(totalSaving), (totalSaving/totalCurrentCost)*100),
9495
}
9596
if i.Skipped {
9697
row[5] = "skipped"
@@ -209,7 +210,7 @@ func (m OptimizationsPage) View() string {
209210
}
210211

211212
return fmt.Sprintf("Current runtime cost: %s, Savings: %s\n%s\n%s",
212-
style.CostStyle.Render(fmt.Sprintf("$%.2f", totalCost)), style.SavingStyle.Render(fmt.Sprintf("$%.2f", savings)),
213+
style.CostStyle.Render(fmt.Sprintf("$%s", utils.FormatFloat(totalCost))), style.SavingStyle.Render(fmt.Sprintf("$%s", utils.FormatFloat(savings))),
213214
m.table.View(),
214215
m.statusBar.View(),
215216
)

Diff for: view/page_optimization_details.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/kaytu-io/kaytu/controller"
88
"github.com/kaytu-io/kaytu/pkg/plugin/proto/src/golang"
99
"github.com/kaytu-io/kaytu/pkg/style"
10+
"github.com/kaytu-io/kaytu/pkg/utils"
1011
"github.com/kaytu-io/kaytu/view/responsive"
1112
"github.com/muesli/reflow/wordwrap"
1213
"strings"
@@ -124,12 +125,12 @@ func (m OptimizationDetailsPage) OnOpen() Page {
124125
dev.DeviceId,
125126
dev.ResourceType,
126127
dev.Runtime,
127-
fmt.Sprintf("$%.2f", dev.CurrentCost),
128+
fmt.Sprintf("$%s", utils.FormatFloat(dev.CurrentCost)),
128129
ifRecommendationExists(func() string {
129-
return fmt.Sprintf("$%.2f", dev.RightSizedCost)
130+
return fmt.Sprintf("$%s", utils.FormatFloat(dev.RightSizedCost))
130131
}),
131132
ifRecommendationExists(func() string {
132-
return fmt.Sprintf("$%.2f", dev.CurrentCost-dev.RightSizedCost)
133+
return fmt.Sprintf("$%s", utils.FormatFloat(dev.CurrentCost-dev.RightSizedCost))
133134
}),
134135
})
135136
}

0 commit comments

Comments
 (0)