...

Source file src/github.com/ory/x/cmdx/printing.go

Documentation: github.com/ory/x/cmdx

     1  package cmdx
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"strings"
     8  	"text/tabwriter"
     9  
    10  	"github.com/spf13/cobra"
    11  	"github.com/spf13/pflag"
    12  )
    13  
    14  type (
    15  	TableHeader interface {
    16  		Header() []string
    17  	}
    18  	TableRow interface {
    19  		TableHeader
    20  		Columns() []string
    21  		Interface() interface{}
    22  	}
    23  	Table interface {
    24  		TableHeader
    25  		Table() [][]string
    26  		Interface() interface{}
    27  		Len() int
    28  	}
    29  
    30  	format string
    31  )
    32  
    33  const (
    34  	FormatQuiet      format = "quiet"
    35  	FormatTable      format = "table"
    36  	FormatJSON       format = "json"
    37  	FormatJSONPretty format = "json-pretty"
    38  	FormatDefault    format = "default"
    39  
    40  	FlagFormat = "format"
    41  
    42  	None = "<none>"
    43  )
    44  
    45  func PrintErrors(cmd *cobra.Command, errs map[string]error) {
    46  	for src, err := range errs {
    47  		fmt.Fprintf(cmd.ErrOrStderr(), "%s: %s\n", src, err.Error())
    48  	}
    49  }
    50  
    51  func PrintRow(cmd *cobra.Command, row TableRow) {
    52  	f := getFormat(cmd)
    53  
    54  	switch f {
    55  	case FormatQuiet:
    56  		if idAble, ok := row.(interface{ ID() string }); ok {
    57  			fmt.Fprintln(cmd.OutOrStdout(), idAble.ID())
    58  			break
    59  		}
    60  		fmt.Fprintln(cmd.OutOrStdout(), row.Columns()[0])
    61  	case FormatJSON:
    62  		printJSON(cmd.OutOrStdout(), row.Interface(), false)
    63  	case FormatJSONPretty:
    64  		printJSON(cmd.OutOrStdout(), row.Interface(), true)
    65  	case FormatTable, FormatDefault:
    66  		w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 8, 1, '\t', 0)
    67  
    68  		fields := row.Columns()
    69  		for i, h := range row.Header() {
    70  			fmt.Fprintf(w, "%s\t%s\t\n", h, fields[i])
    71  		}
    72  
    73  		w.Flush()
    74  	}
    75  }
    76  
    77  func PrintTable(cmd *cobra.Command, table Table) {
    78  	f := getFormat(cmd)
    79  
    80  	switch f {
    81  	case FormatQuiet:
    82  		if table.Len() == 0 {
    83  			fmt.Fprintln(cmd.OutOrStdout())
    84  		}
    85  
    86  		if idAble, ok := table.(interface{ IDs() []string }); ok {
    87  			for _, row := range idAble.IDs() {
    88  				fmt.Fprintln(cmd.OutOrStdout(), row)
    89  			}
    90  			break
    91  		}
    92  
    93  		for _, row := range table.Table() {
    94  			fmt.Fprintln(cmd.OutOrStdout(), row[0])
    95  		}
    96  	case FormatJSON:
    97  		printJSON(cmd.OutOrStdout(), table.Interface(), false)
    98  	case FormatJSONPretty:
    99  		printJSON(cmd.OutOrStdout(), table.Interface(), true)
   100  	default:
   101  		w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 8, 1, '\t', 0)
   102  
   103  		for _, h := range table.Header() {
   104  			fmt.Fprintf(w, "%s\t", h)
   105  		}
   106  		fmt.Fprintln(w)
   107  
   108  		for _, row := range table.Table() {
   109  			fmt.Fprintln(w, strings.Join(row, "\t")+"\t")
   110  		}
   111  
   112  		w.Flush()
   113  	}
   114  }
   115  
   116  func PrintJSONAble(cmd *cobra.Command, d interface{ String() string }) {
   117  	switch getFormat(cmd) {
   118  	default:
   119  		_, _ = fmt.Fprint(cmd.OutOrStdout(), d.String())
   120  	case FormatJSON:
   121  		var v interface{} = d
   122  		if i, ok := d.(interface{ Interface() interface{} }); ok {
   123  			v = i
   124  		}
   125  		printJSON(cmd.OutOrStdout(), v, false)
   126  	case FormatJSONPretty:
   127  		var v interface{} = d
   128  		if i, ok := d.(interface{ Interface() interface{} }); ok {
   129  			v = i
   130  		}
   131  		printJSON(cmd.OutOrStdout(), v, true)
   132  	}
   133  }
   134  
   135  func getQuiet(cmd *cobra.Command) bool {
   136  	q, err := cmd.Flags().GetBool(FlagQuiet)
   137  	// ignore the error here as we use this function also when the flag might not be registered
   138  	if err != nil {
   139  		return false
   140  	}
   141  	return q
   142  }
   143  
   144  func getFormat(cmd *cobra.Command) format {
   145  	q := getQuiet(cmd)
   146  
   147  	if q {
   148  		return FormatQuiet
   149  	}
   150  
   151  	f, err := cmd.Flags().GetString(FlagFormat)
   152  	// unexpected error
   153  	Must(err, "flag access error: %s", err)
   154  
   155  	switch f {
   156  	case string(FormatTable):
   157  		return FormatTable
   158  	case string(FormatJSON):
   159  		return FormatJSON
   160  	case string(FormatJSONPretty):
   161  		return FormatJSONPretty
   162  	default:
   163  		return FormatDefault
   164  	}
   165  }
   166  
   167  func printJSON(w io.Writer, v interface{}, pretty bool) {
   168  	e := json.NewEncoder(w)
   169  	if pretty {
   170  		e.SetIndent("", "  ")
   171  	}
   172  	err := e.Encode(v)
   173  	// unexpected error
   174  	Must(err, "Error encoding JSON: %s", err)
   175  }
   176  
   177  func RegisterJSONFormatFlags(flags *pflag.FlagSet) {
   178  	flags.StringP(FlagFormat, FlagFormat[:1], string(FormatDefault), fmt.Sprintf("Set the output format. One of %s, %s, and %s.", FormatDefault, FormatJSON, FormatJSONPretty))
   179  }
   180  
   181  func RegisterFormatFlags(flags *pflag.FlagSet) {
   182  	RegisterNoiseFlags(flags)
   183  	flags.StringP(FlagFormat, FlagFormat[:1], string(FormatDefault), fmt.Sprintf("Set the output format. One of %s, %s, and %s.", FormatTable, FormatJSON, FormatJSONPretty))
   184  }
   185  

View as plain text