github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/printer/format.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package printer
    21  
    22  import (
    23  	"fmt"
    24  	"os"
    25  	"strings"
    26  
    27  	"github.com/spf13/cobra"
    28  	"k8s.io/klog/v2"
    29  	"k8s.io/kubectl/pkg/cmd/util"
    30  )
    31  
    32  // Format is a type for capturing supported output formats
    33  type Format string
    34  
    35  const (
    36  	Table Format = "table"
    37  	JSON  Format = "json"
    38  	YAML  Format = "yaml"
    39  	Wide  Format = "wide"
    40  )
    41  
    42  var ErrInvalidFormatType = fmt.Errorf("invalid format type")
    43  
    44  func Formats() []string {
    45  	return []string{Table.String(), JSON.String(), YAML.String(), Wide.String()}
    46  }
    47  
    48  func FormatsWithDesc() map[string]string {
    49  	return map[string]string{
    50  		Table.String(): "Output result in human-readable format",
    51  		JSON.String():  "Output result in JSON format",
    52  		YAML.String():  "Output result in YAML format",
    53  		Wide.String():  "Output result in human-readable format with more information",
    54  	}
    55  }
    56  
    57  func (f Format) String() string {
    58  	return string(f)
    59  }
    60  
    61  func (f Format) IsHumanReadable() bool {
    62  	return f == Table || f == Wide
    63  }
    64  
    65  func ParseFormat(s string) (out Format, err error) {
    66  	switch s {
    67  	case Table.String():
    68  		out, err = Table, nil
    69  	case JSON.String():
    70  		out, err = JSON, nil
    71  	case YAML.String():
    72  		out, err = YAML, nil
    73  	case Wide.String():
    74  		out, err = Wide, nil
    75  	default:
    76  		out, err = "", ErrInvalidFormatType
    77  	}
    78  	return
    79  }
    80  
    81  func AddOutputFlag(cmd *cobra.Command, varRef *Format) {
    82  	cmd.Flags().VarP(newOutputValue(Table, varRef), "output", "o",
    83  		fmt.Sprintf("prints the output in the specified format. Allowed values: %s", strings.Join(Formats(), ", ")))
    84  	util.CheckErr(cmd.RegisterFlagCompletionFunc("output",
    85  		func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    86  			var names []string
    87  			for format, desc := range FormatsWithDesc() {
    88  				if strings.HasPrefix(format, toComplete) {
    89  					names = append(names, fmt.Sprintf("%s\t%s", format, desc))
    90  				}
    91  			}
    92  			return names, cobra.ShellCompDirectiveNoFileComp
    93  		}))
    94  }
    95  
    96  func AddOutputFlagForCreate(cmd *cobra.Command, varRef *Format, persistent bool) {
    97  	fs := cmd.Flags()
    98  	if persistent {
    99  		fs = cmd.PersistentFlags()
   100  	}
   101  	fs.VarP(newOutputValue(YAML, varRef), "output", "o", "Prints the output in the specified format. Allowed values: JSON and YAML")
   102  }
   103  
   104  type outputValue Format
   105  
   106  func newOutputValue(defaultValue Format, p *Format) *outputValue {
   107  	*p = defaultValue
   108  	return (*outputValue)(p)
   109  }
   110  
   111  func (o *outputValue) String() string {
   112  	return string(*o)
   113  }
   114  
   115  func (o *outputValue) Type() string {
   116  	return "format"
   117  }
   118  
   119  func (o *outputValue) Set(s string) error {
   120  	outfmt, err := ParseFormat(s)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	*o = outputValue(outfmt)
   125  	return nil
   126  }
   127  
   128  // FatalWithRedColor when an error occurs, sets the red color to print it.
   129  func FatalWithRedColor(msg string, code int) {
   130  	if klog.V(99).Enabled() {
   131  		klog.FatalDepth(2, msg)
   132  	}
   133  	if len(msg) > 0 {
   134  		// add newline if needed
   135  		if !strings.HasSuffix(msg, "\n") {
   136  			msg += "\n"
   137  		}
   138  		fmt.Fprint(os.Stderr, BoldRed(msg))
   139  	}
   140  	os.Exit(code)
   141  }