@@ -36,14 +36,18 @@ class ArgvParser extends Parser
3636 * @param string $desc
3737 * @param bool $allowUnknown
3838 */
39- public function __construct (string $ name , string $ desc = null , bool $ allowUnknown = false )
39+ public function __construct (string $ name , string $ desc = '' , bool $ allowUnknown = false )
4040 {
4141 $ this ->_name = $ name ;
4242 $ this ->_desc = $ desc ;
4343 $ this ->_allowUnknown = $ allowUnknown ;
4444
4545 $ this ->option ('-h, --help ' , 'Show help ' )->on ([$ this , 'showHelp ' ]);
4646 $ this ->option ('-V, --version ' , 'Show version ' )->on ([$ this , 'showVersion ' ]);
47+
48+ $ this ->onExit (function () {
49+ exit (0 );
50+ });
4751 }
4852
4953 /**
@@ -60,6 +64,16 @@ public function version(string $version): self
6064 return $ this ;
6165 }
6266
67+ public function getName (): string
68+ {
69+ return $ this ->_name ;
70+ }
71+
72+ public function getDesc (): string
73+ {
74+ return $ this ->_desc ;
75+ }
76+
6377 /**
6478 * Registers argument definitions (all at once). Only last one can be variadic.
6579 *
@@ -137,6 +151,20 @@ public function on(callable $fn): self
137151 return $ this ;
138152 }
139153
154+ /**
155+ * Register exit handler.
156+ *
157+ * @param callable $fn
158+ *
159+ * @return self
160+ */
161+ public function onExit (callable $ fn ): self
162+ {
163+ $ this ->_events ['_exit ' ] = $ fn ;
164+
165+ return $ this ;
166+ }
167+
140168 protected function handleUnknown (string $ arg , string $ value = null )
141169 {
142170 if ($ this ->_allowUnknown ) {
@@ -197,38 +225,68 @@ public function args(): array
197225
198226 protected function showHelp ()
199227 {
200- echo "{$ this ->_name }, version {$ this ->_version }" . PHP_EOL ;
228+ $ args = $ this ->_arguments ? ' [ARGUMENTS] ' : '' ;
229+ $ opts = $ this ->_options ? ' [OPTIONS] ' : '' ;
230+
231+ ($ w = new Writer )
232+ ->bold ("Command {$ this ->_name }, version {$ this ->_version }" , true )->eol ()
233+ ->comment ($ this ->_desc , true )->eol ()
234+ ->bold ('Usage: ' )->yellow ("{$ this ->_name }{$ args }{$ opts }" , true );
235+
236+ if ($ args ) {
237+ $ this ->showArguments ($ w );
238+ }
239+
240+ if ($ opts ) {
241+ $ this ->showOptions ($ w );
242+ }
243+
244+ $ w ->eol ()->yellow ('Note: <required> [optional] ' )->eol ();
245+
246+ return $ this ->emit ('_exit ' );
247+ }
248+
249+ protected function showArguments (Writer $ w )
250+ {
251+ $ w ->eol ()->boldGreen ('Arguments: ' , true );
252+
253+ $ maxLen = \max (\array_map ('strlen ' , \array_keys ($ this ->_arguments )));
254+
255+ foreach ($ this ->_arguments as $ arg ) {
256+ $ name = $ arg ->name ();
257+ $ name = $ arg ->required () ? "< $ name> " : "[ $ name] " ;
258+ $ w ->bold (' ' . \str_pad ($ name , $ maxLen + 4 ))->comment ($ arg ->desc (), true );
259+ }
260+ }
261+
262+ protected function showOptions (Writer $ w )
263+ {
264+ $ w ->eol ()->boldGreen ('Options: ' , true );
201265
202- // @todo: build help msg!
203- echo "help \n" ;
266+ $ maxLen = \max (\array_map ('strlen ' , \array_keys ($ this ->_options )));
204267
205- _exit ();
268+ foreach ($ this ->_options as $ opt ) {
269+ $ name = $ opt ->short () . '| ' . $ opt ->long ();
270+ $ name = $ opt ->required () ? "< $ name> " : "[ $ name] " ;
271+ $ w ->bold (' ' . \str_pad ($ name , $ maxLen + 9 ))->comment ($ opt ->desc (), true );
272+ }
206273 }
207274
208275 protected function showVersion ()
209276 {
210- echo $ this ->_version . PHP_EOL ;
277+ ( new Writer )-> bold ( $ this ->_version , true ) ;
211278
212- _exit ( );
279+ return $ this -> emit ( ' _exit ' );
213280 }
214281
215- protected function emit (string $ event )
282+ public function emit (string $ event )
216283 {
217284 if (empty ($ this ->_events [$ event ])) {
218285 return ;
219286 }
220287
221288 $ callback = $ this ->_events [$ event ];
222289
223- $ callback ();
224- }
225- }
226-
227- // @codeCoverageIgnoreStart
228- if (!\function_exists (__NAMESPACE__ . '\\_exit ' )) {
229- function _exit ($ code = 0 )
230- {
231- exit ($ code );
290+ return $ callback ();
232291 }
233292}
234- // @codeCoverageIgnoreEnd
0 commit comments