diff --git a/featctl/cmd/get_online_feature.go b/featctl/cmd/get_online_feature.go index 40741fefd..a6fc04bb3 100644 --- a/featctl/cmd/get_online_feature.go +++ b/featctl/cmd/get_online_feature.go @@ -3,10 +3,12 @@ package cmd import ( "context" "encoding/csv" + "fmt" "log" "os" "sort" + "github.com/olekukonko/tablewriter" "github.com/spf13/cast" "github.com/spf13/cobra" @@ -14,10 +16,16 @@ import ( ) var getOnlineFeatureOpt types.GetOnlineFeatureValuesOpt +var getOnlineFeatureOutput *string var getOnlineFeatureCmd = &cobra.Command{ Use: "online-feature", Short: "get online feature values", + PreRun: func(cmd *cobra.Command, args []string) { + if !cmd.Flags().Changed("output") { + getOnlineFeatureOutput = stringPtr(ASCIITable) + } + }, Run: func(cmd *cobra.Command, args []string) { ctx := context.Background() oomStore := mustOpenOomStore(ctx, oomStoreCfg) @@ -28,20 +36,9 @@ var getOnlineFeatureCmd = &cobra.Command{ log.Fatalf("failed getting online features: %v", err) } - header := []string{} - for featureNames := range featureValueMap { - header = append(header, featureNames) - } - sort.Strings(header) - data := []string{} - for _, featureName := range header { - data = append(data, cast.ToString(featureValueMap[featureName])) + if err := printOnlineFeatures(featureValueMap, *getOnlineFeatureOutput); err != nil { + log.Fatalf("failed printing online feature values, error %v\n", err) } - - w := csv.NewWriter(os.Stdout) - _ = w.Write(header) - _ = w.Write(data) - w.Flush() }, } @@ -55,4 +52,62 @@ func init() { flags.StringSliceVar(&getOnlineFeatureOpt.FeatureNames, "feature", nil, "feature names") _ = getOnlineFeatureCmd.MarkFlagRequired("feature") + + getOnlineFeatureOutput = flags.StringP("output", "o", "", "output format") +} + +func printOnlineFeatures(featureValueMap types.FeatureValueMap, output string) error { + switch output { + case CSV: + return printOnlineFeaturesInCSV(featureValueMap) + case ASCIITable: + return printOnlineFeaturesInASCIITable(featureValueMap) + default: + return fmt.Errorf("unsupported output format %s", output) + } +} + +func printOnlineFeaturesInCSV(featureValueMap types.FeatureValueMap) error { + w := csv.NewWriter(os.Stdout) + header := onlineFeatureHeader(featureValueMap) + if err := w.Write(header); err != nil { + return err + } + + record := onlineFeatureRecord(featureValueMap, header) + + if err := w.Write(record); err != nil { + return err + } + w.Flush() + return nil +} + +func printOnlineFeaturesInASCIITable(featureValueMap types.FeatureValueMap) error { + table := tablewriter.NewWriter(os.Stdout) + header := onlineFeatureHeader(featureValueMap) + table.SetHeader(header) + table.SetAutoFormatHeaders(false) + + record := onlineFeatureRecord(featureValueMap, header) + table.Append(record) + table.Render() + return nil +} + +func onlineFeatureHeader(featureValueMap types.FeatureValueMap) []string { + header := make([]string, 0, len(featureValueMap)) + for featureNames := range featureValueMap { + header = append(header, featureNames) + } + sort.Strings(header) + return header +} + +func onlineFeatureRecord(featureValueMap types.FeatureValueMap, header []string) []string { + record := make([]string, 0, len(header)) + for _, featureName := range header { + record = append(record, cast.ToString(featureValueMap[featureName])) + } + return record } diff --git a/featctl/test/test_get_online_feature.sh b/featctl/test/test_get_online_feature.sh index 201530b41..569913a5c 100755 --- a/featctl/test/test_get_online_feature.sh +++ b/featctl/test/test_get_online_feature.sh @@ -12,7 +12,7 @@ expected=' device,model 1,xiaomi-mix3 ' -actual=$(featctl get online-feature --feature model -k 1) +actual=$(featctl get online-feature --feature model -k 1 -o csv) assert_eq "$case" "$expected" "$actual" @@ -21,5 +21,5 @@ expected=' device,model,price 6,apple-iphone11,4999 ' -actual=$(featctl get online-feature --feature model,price -k 6) +actual=$(featctl get online-feature --feature model,price -k 6 -o csv) assert_eq "$case" "$expected" "$actual" diff --git a/featctl/test/test_materialize.sh b/featctl/test/test_materialize.sh index 34561cda1..16cd6bd56 100755 --- a/featctl/test/test_materialize.sh +++ b/featctl/test/test_materialize.sh @@ -13,5 +13,5 @@ expected=' device,model,price 1,xiaomi-mix3,3999 ' -actual=$(featctl get online-feature --feature price,model -k 1) +actual=$(featctl get online-feature --feature price,model -k 1 -o csv) assert_eq "$case" "$expected" "$actual"