github.com/vmware/govmomi@v0.51.0/cli/esx/command.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package esx
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/vmware/govmomi/internal"
    13  )
    14  
    15  type Command struct {
    16  	name []string
    17  	args []string
    18  }
    19  
    20  type CommandInfoItem struct {
    21  	Name        string `xml:"name" json:"name"`
    22  	DisplayName string `xml:"displayName" json:"displayName"`
    23  	Help        string `xml:"help" json:"help"`
    24  }
    25  
    26  type CommandInfoParam struct {
    27  	CommandInfoItem
    28  	Aliases []string `xml:"aliases" json:"aliases"`
    29  	Flag    bool     `xml:"flag" json:"flag"`
    30  }
    31  
    32  type CommandInfoHint struct {
    33  	Key   string `xml:"key" json:"key"`
    34  	Value string `xml:"value" json:"value"`
    35  }
    36  
    37  type CommandInfoHints []CommandInfoHint
    38  
    39  type CommandInfoMethod struct {
    40  	CommandInfoItem
    41  	Param []CommandInfoParam `xml:"param" json:"param"`
    42  	Hints CommandInfoHints   `xml:"hints" json:"hints"`
    43  }
    44  
    45  type CommandInfo struct {
    46  	CommandInfoItem
    47  	Method []CommandInfoMethod `xml:"method" json:"method"`
    48  }
    49  
    50  func NewCommand(args []string) *Command {
    51  	c := &Command{}
    52  
    53  	for i, arg := range args {
    54  		if strings.HasPrefix(arg, "-") {
    55  			c.args = args[i:]
    56  			break
    57  		} else {
    58  			c.name = append(c.name, arg)
    59  		}
    60  	}
    61  
    62  	return c
    63  }
    64  
    65  func (c *Command) Namespace() string {
    66  	return strings.Join(c.name[:len(c.name)-1], ".")
    67  }
    68  
    69  func (c *Command) Name() string {
    70  	return c.name[len(c.name)-1]
    71  }
    72  
    73  func (c *Command) Method() string {
    74  	return "vim.EsxCLI." + strings.Join(c.name, ".")
    75  }
    76  
    77  func (c *Command) Moid() string {
    78  	return "ha-cli-handler-" + strings.Join(c.name[:len(c.name)-1], "-")
    79  }
    80  
    81  type stringList []string
    82  
    83  func (l *stringList) String() string {
    84  	return fmt.Sprint(*l)
    85  }
    86  
    87  func (l *stringList) Set(value string) error {
    88  	*l = append(*l, value)
    89  	return nil
    90  }
    91  
    92  // Parse generates a flag.FlagSet based on the given []CommandInfoParam and
    93  // returns arguments for use with methods.ExecuteSoap
    94  func (c *Command) Parse(params []CommandInfoParam) ([]internal.ReflectManagedMethodExecuterSoapArgument, error) {
    95  	fs := flag.NewFlagSet(strings.Join(c.name, " "), flag.ExitOnError)
    96  	vals := make([]stringList, len(params))
    97  
    98  	for i, p := range params {
    99  		v := &vals[i]
   100  		for _, a := range p.Aliases {
   101  			a = strings.TrimPrefix(a[1:], "-")
   102  			fs.Var(v, a, p.Help)
   103  		}
   104  	}
   105  
   106  	err := fs.Parse(c.args)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  
   111  	args := []internal.ReflectManagedMethodExecuterSoapArgument{}
   112  
   113  	for i, p := range params {
   114  		if len(vals[i]) != 0 {
   115  			args = append(args, c.Argument(p.Name, vals[i]...))
   116  		}
   117  	}
   118  
   119  	return args, nil
   120  }
   121  
   122  func (c *Command) Argument(name string, args ...string) internal.ReflectManagedMethodExecuterSoapArgument {
   123  	var vars []string
   124  	for _, arg := range args {
   125  		vars = append(vars, fmt.Sprintf("<%s>%s</%s>", name, arg, name))
   126  	}
   127  	return internal.ReflectManagedMethodExecuterSoapArgument{
   128  		Name: name,
   129  		Val:  strings.Join(vars, ""),
   130  	}
   131  }
   132  
   133  func (h CommandInfoHints) Formatter() string {
   134  	for _, hint := range h {
   135  		if hint.Key == "formatter" {
   136  			return hint.Value
   137  		}
   138  	}
   139  
   140  	return "simple"
   141  }
   142  
   143  func (h CommandInfoHints) Fields() []string {
   144  	for _, hint := range h {
   145  		if strings.HasPrefix(hint.Key, "fields:") {
   146  			return strings.Split(hint.Value, ",")
   147  		}
   148  	}
   149  
   150  	return nil
   151  }