github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/client/cli/cli.go (about)

     1  // Package cli is a command line interface
     2  package cli
     3  
     4  import (
     5  	"fmt"
     6  	"os"
     7  	osexec "os/exec"
     8  	"strings"
     9  
    10  	"github.com/chzyer/readline"
    11  	"github.com/tickoalcantara12/micro/v3/client/cli/util"
    12  	"github.com/tickoalcantara12/micro/v3/cmd"
    13  	"github.com/urfave/cli/v2"
    14  
    15  	_ "github.com/tickoalcantara12/micro/v3/client/cli/auth"
    16  	_ "github.com/tickoalcantara12/micro/v3/client/cli/config"
    17  	_ "github.com/tickoalcantara12/micro/v3/client/cli/debug"
    18  	_ "github.com/tickoalcantara12/micro/v3/client/cli/gen"
    19  	_ "github.com/tickoalcantara12/micro/v3/client/cli/init"
    20  	_ "github.com/tickoalcantara12/micro/v3/client/cli/network"
    21  	_ "github.com/tickoalcantara12/micro/v3/client/cli/new"
    22  	_ "github.com/tickoalcantara12/micro/v3/client/cli/run"
    23  	_ "github.com/tickoalcantara12/micro/v3/client/cli/shutdown"
    24  	_ "github.com/tickoalcantara12/micro/v3/client/cli/store"
    25  	_ "github.com/tickoalcantara12/micro/v3/client/cli/user"
    26  )
    27  
    28  var (
    29  	prompt = "micro> "
    30  
    31  	// TODO: only run fixed set of commands for security purposes
    32  	commands = map[string]*command{}
    33  )
    34  
    35  type command struct {
    36  	name  string
    37  	usage string
    38  	exec  util.Exec
    39  }
    40  
    41  func Run(c *cli.Context) error {
    42  	// take the first arg as the binary
    43  	binary := os.Args[0]
    44  
    45  	r, err := readline.New(prompt)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	defer r.Close()
    50  
    51  	for {
    52  		args, err := r.Readline()
    53  		if err != nil {
    54  			fmt.Fprint(os.Stdout, err)
    55  			return err
    56  		}
    57  
    58  		args = strings.TrimSpace(args)
    59  
    60  		// skip no args
    61  		if len(args) == 0 {
    62  			continue
    63  		}
    64  
    65  		parts := strings.Split(args, " ")
    66  		if len(parts) == 0 {
    67  			continue
    68  		}
    69  
    70  		cmd := osexec.Command(binary, parts...)
    71  		cmd.Stdin = os.Stdin
    72  		cmd.Stdout = os.Stdout
    73  		cmd.Stderr = os.Stderr
    74  		if err := cmd.Run(); err != nil {
    75  			fmt.Println(string(err.(*osexec.ExitError).Stderr))
    76  		}
    77  	}
    78  
    79  	return nil
    80  }
    81  
    82  func init() {
    83  	cmd.Register(
    84  		&cli.Command{
    85  			Name:   "cli",
    86  			Usage:  "Run the interactive CLI",
    87  			Action: Run,
    88  		},
    89  		&cli.Command{
    90  			Name:   "call",
    91  			Usage:  `Call a service e.g micro call greeter Say.Hello '{"name": "John"}'`,
    92  			Action: util.Print(CallService),
    93  			Flags: []cli.Flag{
    94  				&cli.StringFlag{
    95  					Name:    "address",
    96  					Usage:   "Set the address of the service instance to call",
    97  					EnvVars: []string{"MICRO_ADDRESS"},
    98  				},
    99  				&cli.StringFlag{
   100  					Name:    "output, o",
   101  					Usage:   "Set the output format; json (default), raw",
   102  					EnvVars: []string{"MICRO_OUTPUT"},
   103  				},
   104  				&cli.StringSliceFlag{
   105  					Name:    "metadata",
   106  					Usage:   "A list of key-value pairs to be forwarded as metadata",
   107  					EnvVars: []string{"MICRO_METADATA"},
   108  				},
   109  				&cli.StringFlag{
   110  					Name:  "request_timeout",
   111  					Usage: "timeout duration",
   112  				},
   113  			},
   114  		},
   115  		&cli.Command{
   116  			Name:  "get",
   117  			Usage: `Get resources from micro`,
   118  			Subcommands: []*cli.Command{
   119  				{
   120  					Name:   "service",
   121  					Usage:  "Get a specific service from the registry",
   122  					Action: util.Print(GetService),
   123  				},
   124  			},
   125  		},
   126  		&cli.Command{
   127  			Name:   "stream",
   128  			Usage:  `Create a service stream e.g. micro stream foo Bar.Baz '{"key": "value"}'`,
   129  			Action: util.Print(streamService),
   130  			Flags: []cli.Flag{
   131  				&cli.StringFlag{
   132  					Name:    "output, o",
   133  					Usage:   "Set the output format; json (default), raw",
   134  					EnvVars: []string{"MICRO_OUTPUT"},
   135  				},
   136  				&cli.StringSliceFlag{
   137  					Name:    "metadata",
   138  					Usage:   "A list of key-value pairs to be forwarded as metadata",
   139  					EnvVars: []string{"MICRO_METADATA"},
   140  				},
   141  			},
   142  		},
   143  		&cli.Command{
   144  			Name:   "env",
   145  			Usage:  "Get/set micro cli environment",
   146  			Action: util.Print(listEnvs),
   147  			Subcommands: []*cli.Command{
   148  				{
   149  					Name:   "get",
   150  					Usage:  "Get the currently selected environment",
   151  					Action: util.Print(getEnv),
   152  				},
   153  				{
   154  					Name:   "set",
   155  					Usage:  "Set the environment to use for subsequent commands e.g. micro env set dev",
   156  					Action: util.Print(setEnv),
   157  				},
   158  				{
   159  					Name:   "add",
   160  					Usage:  "Add a new environment e.g. micro env add foo 127.0.0.1:8081",
   161  					Action: util.Print(addEnv),
   162  				},
   163  				{
   164  					Name:   "del",
   165  					Usage:  "Delete an environment from your list e.g. micro env del foo",
   166  					Action: util.Print(delEnv),
   167  				},
   168  			},
   169  		},
   170  		&cli.Command{
   171  			Name:   "services",
   172  			Usage:  "List services in the registry",
   173  			Action: util.Print(ListServices),
   174  		},
   175  	)
   176  }