github.com/WindomZ/go-commander@v1.2.2/option.go (about)

     1  package commander
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  )
     8  
     9  // _Option
    10  type _Option struct {
    11  	actor                // actor
    12  	usage     string     // usage
    13  	required  bool       // option required
    14  	desc      string     // desc
    15  	show      bool       // show on options
    16  	line      bool       // show on options in new line
    17  	arguments _Arguments // arguments
    18  }
    19  
    20  func newOption(usage string, args ...interface{}) *_Option {
    21  	o := &_Option{
    22  		usage: strings.TrimSpace(usage),
    23  	}
    24  	o.regexpNames()
    25  	o.regexpArguments()
    26  	o.regexpRequired()
    27  	if len(args) >= 1 {
    28  		desc, _ := args[0].(string)
    29  		o.Description(desc)
    30  	}
    31  	if len(args) >= 2 {
    32  		o.setAction(args[1])
    33  	}
    34  	if len(args) >= 3 {
    35  		defs := make([]string, 0, len(args)-2)
    36  		for _, arg := range args[2:] {
    37  			defs = append(defs, fmt.Sprintf("%v", arg))
    38  		}
    39  		def := fmt.Sprintf("[default: %v]", strings.Join(defs, ","))
    40  		if len(o.desc) != 0 {
    41  			o.desc += " " + def
    42  		} else {
    43  			o.desc = def
    44  		}
    45  	}
    46  	return o
    47  }
    48  
    49  func (o *_Option) regexpNames() {
    50  	o.names = regexpOption(o.usage)
    51  }
    52  
    53  func (o *_Option) regexpArguments() {
    54  	o.arguments.Set(o.usage)
    55  }
    56  
    57  func (o *_Option) regexpRequired() {
    58  	if strings.HasPrefix(o.usage, "(") {
    59  		o.required = true
    60  	}
    61  }
    62  
    63  func (o _Option) Valid() bool {
    64  	return len(o.names) != 0 && len(o.usage) != 0
    65  }
    66  
    67  func (o _Option) Name() string {
    68  	return strings.Join(o.names, "|")
    69  }
    70  
    71  func (o _Option) Names() []string {
    72  	return o.names
    73  }
    74  
    75  func (o _Option) IsRequired() bool {
    76  	return o.required
    77  }
    78  
    79  func (o _Option) IsOptional() bool {
    80  	return !o.IsRequired()
    81  }
    82  
    83  func (o *_Option) Description(desc string) *_Option {
    84  	o.desc = strings.TrimSpace(desc)
    85  	o.show = len(o.desc) != 0
    86  	return o
    87  }
    88  
    89  func (o *_Option) Aliases(aliases []string) *_Option {
    90  	s := strings.TrimSpace(strings.Join(aliases, " "))
    91  	if len(s) != 0 {
    92  		o.usage += " " + s
    93  		o.regexpNames()
    94  		o.regexpArguments()
    95  		o.regexpRequired()
    96  	}
    97  	return o
    98  }
    99  
   100  func (o _Option) UsageString(ones ...bool) string {
   101  	if ok, _ := regexp.MatchString(`^[\[(].+[)\]]$`, o.usage); !ok || len(o.names) > 1 {
   102  		strs := make([]string, len(o.names))
   103  		arg := strings.Join(o.arguments.Get(), " ")
   104  		for i, name := range o.names {
   105  			if len(arg) != 0 {
   106  				strs[i] = name + "=" + arg
   107  			} else {
   108  				strs[i] = name
   109  			}
   110  		}
   111  		s := strings.Join(strs, "|")
   112  
   113  		if o.line && len(ones) != 0 && ones[0] {
   114  		} else if o.line || o.IsRequired() {
   115  			s = fmt.Sprintf("(%s)", s)
   116  		} else {
   117  			s = fmt.Sprintf("[%s]", s)
   118  		}
   119  		return s
   120  	}
   121  	return regexp.MustCompile(`(\s*,\s*-)|(\s-)`).ReplaceAllString(o.usage, "|-")
   122  }
   123  
   124  func (o _Option) OptionString() (s string) {
   125  	if !o.show {
   126  		return ""
   127  	}
   128  	s = regexp.MustCompile(`^[\[(].+[)\]]$`).
   129  		ReplaceAllStringFunc(o.usage, func(str string) string {
   130  			if len(str) > 2 {
   131  				return str[1 : len(str)-1]
   132  			}
   133  			return str
   134  		})
   135  	s = regexp.MustCompile(`(\s*[,|]\s*-)`).ReplaceAllString(s, " -")
   136  	s = Format.Description(s, o.desc)
   137  	return
   138  }
   139  
   140  func (o _Option) run(c Context) _Result {
   141  	if r := o.actor.run(c); r != nil && r.Break() {
   142  		return r
   143  	}
   144  	return nil
   145  }