@@ -111,13 +111,6 @@ protected function configure(): void
111111 //
112112 }
113113
114- public function setBoolMapping (array $ boolMapping ): SimpleConsole
115- {
116- $ this ->boolMapping = $ boolMapping ;
117-
118- return $ this ;
119- }
120-
121114 protected function doExecute (): int |bool
122115 {
123116 return 0 ;
@@ -127,6 +120,7 @@ public function execute(?array $argv = null, ?\Closure $main = null): int
127120 {
128121 $ argv = $ argv ?? $ _SERVER ['argv ' ];
129122 $ main ??= $ this ->doExecute (...);
123+ $ main ->bindTo ($ this );
130124
131125 try {
132126 if (!$ this ->disableDefaultParameters ) {
@@ -139,13 +133,10 @@ public function execute(?array $argv = null, ?\Closure $main = null): int
139133 $ this ->params = $ this ->parser ->parse ($ argv );
140134
141135 if (!$ this ->disableDefaultParameters ) {
142- if ($ v = $ this ->get ('verbosity ' )) {
143- $ this ->verbosity = $ v ;
144- }
136+ $ this ->verbosity = (int ) $ this ->get ('verbosity ' );
145137
146138 if ($ this ->get ('help ' )) {
147139 $ this ->showHelp ();
148-
149140 return static ::SUCCESS ;
150141 }
151142 }
@@ -158,7 +149,7 @@ public function execute(?array $argv = null, ?\Closure $main = null): int
158149 $ exitCode = 255 ;
159150 }
160151
161- return $ exitCode ;
152+ return ( int ) $ exitCode ;
162153 } catch (\Throwable $ e ) {
163154 return $ this ->handleException ($ e );
164155 }
@@ -171,43 +162,24 @@ protected function help(): string
171162
172163 public function showHelp (): void
173164 {
174- $ help = ParameterDescriptor::describe ($ this ->parser , 'command ' , $ this ->help ());
175-
176- $ this ->writeln ($ help );
165+ $ this ->writeln (ParameterDescriptor::describe ($ this ->parser , 'command ' , $ this ->help ()));
177166 }
178167
179- public function write (string $ message ): static
168+ public function write (string $ message, bool $ err = false ): static
180169 {
181- fwrite ($ this ->stdout , $ message );
182-
170+ fwrite ($ err ? $ this ->stderr : $ this ->stdout , $ message );
183171 return $ this ;
184172 }
185173
186- public function writeln (string $ message = '' ): static
174+ public function writeln (string $ message = '' , bool $ err = false ): static
187175 {
188- $ this ->write ($ message . "\n" );
189-
176+ $ this ->write ($ message . "\n" , $ err );
190177 return $ this ;
191178 }
192179
193- public function newLine (int $ lines = 1 ): static
180+ public function newLine (int $ lines = 1 , bool $ err = false ): static
194181 {
195- $ this ->write (str_repeat ("\n" , $ lines ));
196-
197- return $ this ;
198- }
199-
200- public function writeErr (string $ message ): static
201- {
202- fwrite ($ this ->stderr , $ message );
203-
204- return $ this ;
205- }
206-
207- public function writelnErr (string $ message = '' ): static
208- {
209- $ this ->writeErr ($ message . "\n" );
210-
182+ $ this ->write (str_repeat ("\n" , $ lines ), $ err );
211183 return $ this ;
212184 }
213185
@@ -247,21 +219,67 @@ public function mapBoolean($in): bool|null
247219 return null ;
248220 }
249221
222+ public function exec (string $ cmd , ?\Closure $ output = null ): int
223+ {
224+ $ this ->writeln ('>> ' . $ cmd );
225+
226+ $ descriptorspec = [
227+ 0 => ["pipe " , "r " ], // stdin
228+ 1 => ["pipe " , "w " ], // stdout
229+ 2 => ["pipe " , "w " ] // stderr
230+ ];
231+
232+ if ($ process = proc_open ($ cmd , $ descriptorspec , $ pipes )) {
233+ while (($ out = fgets ($ pipes [1 ])) || $ err = fgets ($ pipes [2 ])) {
234+ if (isset ($ out [0 ])) {
235+ if ($ output ) {
236+ $ output ($ out , false );
237+ } else {
238+ $ this ->write ($ out , false );
239+ }
240+ }
241+
242+ if (isset ($ err [0 ])) {
243+ if ($ output ) {
244+ $ output ($ err , true );
245+ } else {
246+ $ this ->write ($ err , true );
247+ }
248+ }
249+ }
250+
251+ return proc_close ($ process );
252+ }
253+
254+ return 255 ;
255+ }
256+
257+ public function mustExec (string $ cmd , ?\Closure $ output = null ): int
258+ {
259+ $ result = $ this ->exec ($ cmd , $ output );
260+
261+ if ($ result !== 0 ) {
262+ throw new \RuntimeException ('Command " ' . $ cmd . '" failed with code ' . $ result );
263+ }
264+
265+ return $ result ;
266+ }
267+
250268 protected function handleException (\Throwable $ e ): int
251269 {
252270 $ v = $ this ->verbosity ;
253271
254272 if ($ e instanceof InvalidParameterException) {
255- $ this ->writelnErr ('[Warning] ' . $ e ->getMessage ())
256- ->writelnErr ( )
257- ->writelnErr ('HELP ' );
273+ $ this ->writeln ('[Warning] ' . $ e ->getMessage (), true )
274+ ->newLine (err: true )
275+ ->writeln ('HELP ' , true );
258276 } else {
259- $ this ->writelnErr ('[Error] ' . $ e ->getMessage ());
277+ $ this ->writeln ('[Error] ' . $ e ->getMessage (), true );
260278 }
261279
262280 if ($ v > 0 ) {
263- $ this ->writelnErr ('[Backtrace]: ' )
264- ->writeErr ($ e ->getTraceAsString ());
281+ $ this ->writeln ('[Backtrace]: ' , true )
282+ ->writeln ($ e ->getTraceAsString (), true );
265283 }
266284
267285 $ code = $ e ->getCode ();
@@ -344,7 +362,7 @@ public function addParameter(
344362
345363 foreach ($ name as $ n ) {
346364 if (!str_starts_with ($ n , '- ' )) {
347- throw new \RuntimeException ('Argument name cannot contains "|" sign. ' );
365+ throw new \InvalidArgumentException ('Argument name cannot contains "|" sign. ' );
348366 }
349367 }
350368 }
@@ -353,7 +371,7 @@ public function addParameter(
353371
354372 foreach ((array ) $ parameter ->name as $ n ) {
355373 if (in_array ($ n , $ this ->existsNames , true )) {
356- throw new \RuntimeException ('Duplicate parameter name " ' . $ n . '" ' );
374+ throw new \InvalidArgumentException ('Duplicate parameter name " ' . $ n . '" ' );
357375 }
358376 }
359377
@@ -506,11 +524,7 @@ private function parseLongOption(string $token): void
506524
507525 private function parseArgument (string $ token ): void
508526 {
509- $ c = $ this ->currentArgument ;
510-
511- $ arg = $ this ->getArgumentByIndex ($ c );
512-
513- if ($ arg ) {
527+ if ($ arg = $ this ->getArgumentByIndex ($ this ->currentArgument )) {
514528 $ this ->values [$ arg ->primaryName ] = $ arg ->isArray ? [$ token ] : $ token ;
515529 } elseif (($ last = $ this ->getLastArgument ()) && $ last ->isArray ) {
516530 $ this ->values [$ last ->primaryName ][] = $ token ;
@@ -544,9 +558,8 @@ public function setOptionValue(string $name, mixed $value = null): void
544558 throw new InvalidParameterException ('Option " ' . $ option ->primaryName . '" does not accept value. ' );
545559 }
546560
561+ // Try get option value from next token
547562 if (\in_array ($ value , ['' , null ], true ) && $ option ->acceptValue && \count ($ this ->tokens )) {
548- // if option accepts an optional or mandatory argument
549- // let's see if there is one provided
550563 $ next = array_shift ($ this ->tokens );
551564
552565 if ((isset ($ next [0 ]) && '- ' !== $ next [0 ]) || \in_array ($ next , ['' , null ], true )) {
@@ -678,33 +691,33 @@ public function __construct(
678691 if (is_array ($ this ->name )) {
679692 foreach ($ this ->name as $ i => $ n ) {
680693 if (!str_starts_with ($ n , '-- ' ) && strlen ($ n ) > 2 ) {
681- throw new InvalidParameterException ('Invalid option name " ' . $ n . '" ' );
694+ throw new \ InvalidArgumentException ('Invalid option name " ' . $ n . '" ' );
682695 }
683696
684697 $ this ->name [$ i ] = ltrim ($ n , '- ' );
685698 }
686699 }
687700
688701 if ($ this ->isArray && !is_array ($ this ->defaultValue )) {
689- throw new InvalidParameterException ("Default value of \"{$ this ->primaryName }\" must be an array. " );
702+ throw new \ InvalidArgumentException ("Default value of \"{$ this ->primaryName }\" must be an array. " );
690703 }
691704
692705 if ($ this ->isArg ) {
693706 if ($ this ->negatable ) {
694- throw new InvalidParameterException (
707+ throw new \ InvalidArgumentException (
695708 "Argument \"{$ this ->primaryName }\" cannot be negatable. "
696709 );
697710 }
698711 } else {
699712 if ($ this ->negatable && $ this ->required ) {
700- throw new InvalidParameterException (
713+ throw new \ InvalidArgumentException (
701714 "Negatable option \"{$ this ->primaryName }\" cannot be required. "
702715 );
703716 }
704717 }
705718
706719 if ($ this ->required && $ this ->default !== null ) {
707- throw new InvalidParameterException (
720+ throw new \ InvalidArgumentException (
708721 "Default value of \"{$ this ->primaryName }\" cannot be set when required is true. "
709722 );
710723 }
@@ -749,6 +762,7 @@ public function validate(mixed $value): void
749762 "Invalid value type for \"{$ this ->primaryName }\". Expected int. "
750763 );
751764 }
765+ break ;
752766 case ParameterType::FLOAT :
753767 if (!is_numeric ($ value ) || ((string ) (float ) $ value ) !== $ value ) {
754768 throw new InvalidParameterException (
@@ -992,6 +1006,5 @@ enum ParameterType
9921006
9931007 class InvalidParameterException extends \RuntimeException
9941008 {
995- //
9961009 }
9971010}
0 commit comments