@@ -2,27 +2,27 @@ package goNixArgParser
22
33import (
44 "bytes"
5- "os "
5+ "io "
66 "path"
77)
88
99func NewCommand (
1010 names []string ,
1111 summary , mergeFlagPrefix string ,
12- restsSigns , groupSeps , undefFlagPrefixes []string ,
12+ restsSigns , groupSeps , assignSigns , undefFlagPrefixes []string ,
1313) * Command {
1414 return & Command {
1515 names : names ,
1616 summary : summary ,
17- options : NewOptionSet (mergeFlagPrefix , restsSigns , groupSeps , undefFlagPrefixes ),
17+ options : NewOptionSet (mergeFlagPrefix , restsSigns , groupSeps , assignSigns , undefFlagPrefixes ),
1818 subCommands : []* Command {},
1919 }
2020}
2121
2222func NewSimpleCommand (name , summary string , aliasNames ... string ) * Command {
23- names := make ([]string , 0 , 1 + len (aliasNames ))
24- names = append ( names , name )
25- names = append (names , aliasNames ... )
23+ names := make ([]string , 1 + len (aliasNames ))
24+ names [ 0 ] = name
25+ copy (names [ 1 :] , aliasNames )
2626
2727 return & Command {
2828 names : names ,
@@ -35,9 +35,9 @@ func NewSimpleCommand(name, summary string, aliasNames ...string) *Command {
3535func (c * Command ) NewSubCommand (
3636 names []string ,
3737 summary , mergeFlagPrefix string ,
38- restsSigns , groupSeps , undefFlagPrefixes []string ,
38+ restsSigns , groupSeps , assignSigns , undefFlagPrefixes []string ,
3939) * Command {
40- subCommand := NewCommand (names , summary , mergeFlagPrefix , restsSigns , groupSeps , undefFlagPrefixes )
40+ subCommand := NewCommand (names , summary , mergeFlagPrefix , restsSigns , groupSeps , assignSigns , undefFlagPrefixes )
4141 c .subCommands = append (c .subCommands , subCommand )
4242 return subCommand
4343}
@@ -58,10 +58,6 @@ func (c *Command) hasName(name string) bool {
5858}
5959
6060func (c * Command ) GetSubCommand (name string ) * Command {
61- if c .subCommands == nil {
62- return nil
63- }
64-
6561 for _ , cmd := range c .subCommands {
6662 if cmd .hasName (name ) {
6763 return cmd
@@ -79,7 +75,9 @@ func (c *Command) Name() (name string) {
7975}
8076
8177func (c * Command ) Names () []string {
82- return c .names
78+ names := make ([]string , len (c .names ))
79+ copy (names , c .names )
80+ return names
8381}
8482
8583func (c * Command ) Summary () string {
@@ -94,116 +92,107 @@ func (c *Command) SubCommands() []*Command {
9492 return c .subCommands
9593}
9694
97- func (c * Command ) getNormalizedArgs ( initArgs []string ) (* Command , [] * Arg ) {
98- cmd : = c
95+ func (c * Command ) getLeafCmd ( args []string ) (explicitCmd * Command , inferredCmd * Command , cmdPaths [] string ) {
96+ inferredCmd = c
9997
100- if len (initArgs ) == 0 {
101- return cmd , [] * Arg {}
98+ if len (args ) == 0 {
99+ return explicitCmd , inferredCmd , [] string {}
102100 }
103101
104- args := make ([] * Arg , 0 , len ( initArgs ))
105-
106- for i , arg := range initArgs {
107- if i == 0 && cmd . hasName ( arg ) {
108- args = append ( args , NewArg ( cmd . Name (), CommandArg ))
109- } else if subCmd := cmd . GetSubCommand ( arg ); subCmd != nil {
110- args = append ( args , NewArg ( subCmd . Name (), CommandArg ))
111- cmd = subCmd
102+ for i , arg := range args {
103+ if i == 0 && inferredCmd . hasName ( arg ) {
104+ explicitCmd = c
105+ cmdPaths = append ( cmdPaths , inferredCmd . Name ())
106+ } else if subCmd := inferredCmd . GetSubCommand ( arg ); subCmd != nil {
107+ explicitCmd = subCmd
108+ inferredCmd = subCmd
109+ cmdPaths = append ( cmdPaths , inferredCmd . Name ())
112110 } else {
113111 break
114112 }
115113 }
116114
117- return cmd , args
115+ return
118116}
119117
120- func (c * Command ) splitCommandsArgs ( initArgs , initConfigs []string ) (
121- argsLeafCmd * Command ,
122- commands , optionSetInitArgs , optionSetInitConfigs []string ,
118+ func (c * Command ) extractCmdOptionArgs ( specifiedArgs , configArgs []string ) (
119+ specifiedCmd * Command ,
120+ cmdPaths , specifiedOptionArgs , configOptionArgs []string ,
123121) {
124- argsLeafCmd , argCmds := c .getNormalizedArgs ( initArgs )
125- configsLeafCmd , configCmds := c .getNormalizedArgs ( initConfigs )
122+ _ , specifiedCmd , specifiedCmdPaths := c .getLeafCmd ( specifiedArgs )
123+ explicitConfigCmd , configCmd , configCmdPaths := c .getLeafCmd ( configArgs )
126124
127- commands = []string {}
128- for _ , arg := range argCmds {
129- commands = append (commands , arg .Text )
130- }
125+ cmdPaths = specifiedCmdPaths
131126
132- optionSetInitArgs = initArgs [len (argCmds ):]
127+ specifiedOptionArgs = specifiedArgs [len (specifiedCmdPaths ):]
133128
134- if argsLeafCmd == configsLeafCmd {
135- optionSetInitConfigs = initConfigs [len (configCmds ):]
129+ if specifiedCmd == configCmd {
130+ configOptionArgs = configArgs [len (configCmdPaths ):]
131+ } else if explicitConfigCmd == nil {
132+ configOptionArgs = configArgs
136133 } else {
137- optionSetInitConfigs = []string {}
134+ configOptionArgs = []string {}
138135 }
139136
140137 return
141138}
142139
143- func (c * Command ) Parse (initArgs , initConfigs []string ) * ParseResult {
144- leafCmd , commands , optionSetInitArgs , optionSetInitConfigs := c .splitCommandsArgs ( initArgs , initConfigs )
145- result := leafCmd .options .Parse (optionSetInitArgs , optionSetInitConfigs )
146- result .commands = commands
140+ func (c * Command ) Parse (specifiedArgs , configArgs []string ) * ParseResult {
141+ cmd , cmdPaths , specifiedOptionArgs , configOptionArgs := c .extractCmdOptionArgs ( specifiedArgs , configArgs )
142+ result := cmd .options .Parse (specifiedOptionArgs , configOptionArgs )
143+ result .commands = cmdPaths
147144
148145 return result
149146}
150147
151- func (c * Command ) ParseGroups (initArgs , initConfigs []string ) (results []* ParseResult ) {
152- leafCmd , commands , optionSetInitArgs , optionSetInitConfigs := c .splitCommandsArgs ( initArgs , initConfigs )
148+ func (c * Command ) ParseGroups (specifiedArgs , configArgs []string ) (results []* ParseResult ) {
149+ cmd , cmdPaths , specifiedOptionArgs , configOptionArgs := c .extractCmdOptionArgs ( specifiedArgs , configArgs )
153150
154- if len (optionSetInitArgs ) == 0 && len (optionSetInitConfigs ) == 0 {
155- result := leafCmd .options .Parse (optionSetInitArgs , optionSetInitConfigs )
151+ if len (specifiedOptionArgs ) == 0 && len (configOptionArgs ) == 0 {
152+ result := cmd .options .Parse (specifiedOptionArgs , configOptionArgs )
156153 results = append (results , result )
157154 } else {
158- results = leafCmd .options .ParseGroups (optionSetInitArgs , optionSetInitConfigs )
155+ results = cmd .options .ParseGroups (specifiedOptionArgs , configOptionArgs )
159156 }
160157
161158 for _ , result := range results {
162- result .commands = commands
159+ result .commands = cmdPaths
163160 }
164161
165162 return results
166163}
167164
168- func (c * Command ) GetHelp () []byte {
165+ func (c * Command ) OutputHelp (w io.Writer ) {
166+ newline := []byte {'\n' }
169167 buffer := & bytes.Buffer {}
170168
171169 name := c .Name ()
172170 if len (name ) > 0 {
173- buffer .WriteString (path .Base (name ))
174- buffer .WriteString (": " )
171+ io .WriteString (w , path .Base (name ))
172+ io .WriteString (w , ": " )
175173 }
176174 if len (c .summary ) > 0 {
177- buffer .WriteString (c .summary )
175+ io .WriteString (w , c .summary )
178176 }
179177 if buffer .Len () > 0 {
180178 buffer .WriteByte ('\n' )
181179 } else {
182- buffer .WriteString ("Usage:\n " )
180+ io .WriteString (w , "Usage:\n " )
183181 }
184182
185- optionsHelp := c .options .GetHelp ()
186- if len (optionsHelp ) > 0 {
187- buffer .WriteString ("\n Options:\n \n " )
188- buffer .Write (optionsHelp )
189- }
183+ io .WriteString (w , "\n Options:\n \n " )
184+ c .options .OutputHelp (w )
190185
191186 if len (c .subCommands ) > 0 {
192- buffer .WriteString ("\n Sub commands:\n \n " )
187+ io .WriteString (w , "\n Sub commands:\n \n " )
193188 for _ , cmd := range c .subCommands {
194- buffer .WriteString (cmd .Name ())
195- buffer . WriteByte ( '\n' )
189+ io .WriteString (w , cmd .Name ())
190+ w . Write ( newline )
196191 if len (cmd .summary ) > 0 {
197- buffer .WriteString (cmd .summary )
198- buffer . WriteByte ( '\n' )
192+ io .WriteString (w , cmd .summary )
193+ w . Write ( newline )
199194 }
200- buffer . WriteByte ( '\n' )
195+ w . Write ( newline )
201196 }
202197 }
203-
204- return buffer .Bytes ()
205- }
206-
207- func (c * Command ) PrintHelp () {
208- os .Stdout .Write (c .GetHelp ())
209198}
0 commit comments