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 }