github.com/esnet/gdg@v0.6.1-0.20240412190737-6b6eba9c14d8/cli/support/root.go (about)

     1  package support
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"github.com/bep/simplecobra"
     9  	appconfig "github.com/esnet/gdg/internal/log"
    10  	"github.com/esnet/gdg/internal/service"
    11  	"github.com/jedib0t/go-pretty/v6/table"
    12  	"github.com/spf13/cobra"
    13  	"log"
    14  	"os"
    15  )
    16  
    17  var (
    18  	DefaultConfig string
    19  )
    20  
    21  // RootCommand struct wraps the root command and supporting services needed
    22  type RootCommand struct {
    23  	NameP  string
    24  	isInit bool
    25  
    26  	GrafanaSvc func() service.GrafanaService
    27  
    28  	ctx                  context.Context
    29  	initThis             *simplecobra.Commandeer
    30  	initRunner           *simplecobra.Commandeer
    31  	failWithCobraCommand bool
    32  	failRun              bool
    33  
    34  	TableObj table.Writer
    35  
    36  	CommandEntries []simplecobra.Commander
    37  }
    38  
    39  func (cmd *RootCommand) Render(command *cobra.Command, data interface{}) {
    40  	output, _ := command.Flags().GetString("output")
    41  	if output == "json" {
    42  		data, err := json.MarshalIndent(data, "", "    ")
    43  		if err != nil {
    44  			log.Fatal("unable to render result to JSON", err)
    45  		}
    46  		fmt.Print(string(data))
    47  
    48  	} else {
    49  		cmd.TableObj.Render()
    50  	}
    51  
    52  }
    53  
    54  // RootOption used to configure the Root Command struct
    55  type RootOption func(command *RootCommand)
    56  
    57  // NewRootCmd Allows to construct a root command passing any number of arguments to set RootCommand Options
    58  func NewRootCmd(root *RootCommand, options ...RootOption) *RootCommand {
    59  	if root == nil {
    60  		root = &RootCommand{}
    61  	}
    62  	for _, o := range options {
    63  		o(root)
    64  	}
    65  	return root
    66  }
    67  
    68  // Commands returns a list of Cobra commands
    69  func (c *RootCommand) Commands() []simplecobra.Commander {
    70  	return c.CommandEntries
    71  }
    72  
    73  // PreRun executed prior to command invocation
    74  func (c *RootCommand) PreRun(this, runner *simplecobra.Commandeer) error {
    75  	c.isInit = true
    76  	c.initThis = this
    77  	c.initRunner = runner
    78  	c.initConfiguration()
    79  	return nil
    80  }
    81  
    82  // initConfiguration Loads configuration, and setups fail over case
    83  func (c *RootCommand) initConfiguration() {
    84  	appconfig.InitializeAppLogger(os.Stdout, os.Stderr, false)
    85  
    86  }
    87  
    88  // Name returns the cli command name
    89  func (c *RootCommand) Name() string {
    90  	return c.NameP
    91  }
    92  
    93  // Run invokes the CLI command
    94  func (c *RootCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
    95  	if c.failRun {
    96  		return errors.New("failRun")
    97  	}
    98  	c.ctx = ctx
    99  	return nil
   100  }
   101  
   102  // Init invoked to Initialize the RootCommand object
   103  func (c *RootCommand) Init(cd *simplecobra.Commandeer) error {
   104  	if c.failWithCobraCommand {
   105  		return errors.New("failWithCobraCommand")
   106  	}
   107  	cmd := cd.CobraCommand
   108  
   109  	persistentFlags := cmd.PersistentFlags()
   110  	persistentFlags.StringP("config", "c", "", "Configuration Override")
   111  	persistentFlags.StringP("output", "", "table", "output format: (table, json)")
   112  	if c.TableObj == nil {
   113  		c.TableObj = table.NewWriter()
   114  		c.TableObj.SetOutputMirror(os.Stdout)
   115  		c.TableObj.SetStyle(table.StyleLight)
   116  	}
   117  
   118  	return nil
   119  }