@@ -90,70 +90,68 @@ protected function configure()
9090 }
9191
9292 /**
93- * validate input arguments and options
94- * @return bool
93+ * @return InputDefinition
9594 */
96- public function validateInput ()
95+ protected function createDefinition ()
9796 {
98- if (!$ definition = $ this ->definition ) {
99- return true ;
100- }
97+ $ this ->definition = new InputDefinition ();
10198
102- $ givenArgs = $ errArgs = [];
99+ return $ this ->definition ;
100+ }
103101
104- foreach ($ this ->input ->getArgs () as $ key => $ value ) {
105- if (is_int ($ key )) {
106- $ givenArgs [$ key ] = $ value ;
107- } else {
108- $ errArgs [] = $ key ;
109- }
110- }
102+ /**
103+ * run command
104+ * @return int
105+ */
106+ public function run ()
107+ {
108+ // load input definition configure
109+ $ this ->configure ();
111110
112- if (count ( $ errArgs ) > 0 ) {
113- throw new \ RuntimeException ( sprintf ( ' Unknown arguments (error: "%s"). ' , implode ( ' , ' , $ errArgs )) );
111+ if ($ this -> input -> sameOpt ([ ' h ' , ' help ' ]) ) {
112+ return $ this -> showHelp ( );
114113 }
115114
116- $ defArgs = $ definition ->getArguments ();
117- $ missingArgs = array_filter (array_keys ($ defArgs ), function ($ name , $ key ) use ($ definition , $ givenArgs ) {
118- return !array_key_exists ($ key , $ givenArgs ) && $ definition ->argumentIsRequired ($ name );
119- }, ARRAY_FILTER_USE_BOTH );
120-
121- if (count ($ missingArgs ) > 0 ) {
122- throw new \RuntimeException (sprintf ('Not enough arguments (missing: "%s"). ' , implode (', ' , $ missingArgs )));
123- }
115+ $ status = 0 ;
124116
125- $ index = 0 ;
126- $ args = [] ;
117+ try {
118+ App:: fire (App:: ON_BEFORE_EXEC , [ $ this ]) ;
127119
128- foreach ($ defArgs as $ name => $ conf ) {
129- $ args [$ name ] = $ givenArgs [$ index ];
130- $ index ++;
131- }
120+ if (true !== $ this ->beforeRun ()) {
121+ return -1 ;
122+ }
132123
133- $ this ->input ->setArgs ($ args );
124+ $ status = $ this ->execute ($ this ->input , $ this ->output );
125+ $ this ->afterRun ();
134126
135- // check options
136- // $givenOpts = $this->input->getOpts();
137- // $defOpts = $definition->getOptions();
127+ App::fire (App::ON_AFTER_EXEC , [$ this ]);
128+ } catch (\Throwable $ e ) {
129+ App::fire (App::ON_EXEC_ERROR , [$ e , $ this ]);
130+ $ this ->handleRuntimeException ($ e );
131+ }
138132
139- return true ;
133+ return $ status ;
140134 }
141135
142136 /**
143- * @return InputDefinition
137+ * do execute
138+ * @param Input $input
139+ * @param Output $output
140+ * @return int
144141 */
145- protected function createDefinition ()
142+ abstract protected function execute ($ input , $ output );
143+
144+ protected function showHelp ()
146145 {
147- $ this ->definition = new InputDefinition ();
146+ // 创建了 InputDefinition , 则使用它的信息。
147+ // 不会再解析和使用命令的注释。
148+ if ($ def = $ this ->getDefinition ()) {
149+ $ this ->output ->mList ($ def ->getSynopsis ());
148150
149- return $ this ->definition ;
151+ return true ;
152+ }
150153 }
151154
152- /**
153- * run
154- */
155- abstract public function run ();
156-
157155 /**
158156 * beforeRun
159157 */
@@ -177,7 +175,78 @@ protected function beforeRun()
177175 }
178176
179177 // do validate input arg and opt
180- $ this ->validateInput ();
178+ return $ this ->validateInput ();
179+ }
180+
181+ /**
182+ * validate input arguments and options
183+ * @return bool
184+ */
185+ public function validateInput ()
186+ {
187+ if (!$ def = $ this ->definition ) {
188+ return true ;
189+ }
190+
191+ $ in = $ this ->input ;
192+ $ givenArgs = $ errArgs = [];
193+
194+ foreach ($ in ->getArgs () as $ key => $ value ) {
195+ if (is_int ($ key )) {
196+ $ givenArgs [$ key ] = $ value ;
197+ } else {
198+ $ errArgs [] = $ key ;
199+ }
200+ }
201+
202+ if (count ($ errArgs ) > 0 ) {
203+ $ this ->output ->liteError (sprintf ('Unknown arguments (error: "%s"). ' , implode (', ' , $ errArgs )));
204+
205+ return false ;
206+ }
207+
208+ $ defArgs = $ def ->getArguments ();
209+ $ missingArgs = array_filter (array_keys ($ defArgs ), function ($ name , $ key ) use ($ def , $ givenArgs ) {
210+ return !array_key_exists ($ key , $ givenArgs ) && $ def ->argumentIsRequired ($ name );
211+ }, ARRAY_FILTER_USE_BOTH );
212+
213+ if (count ($ missingArgs ) > 0 ) {
214+ $ this ->output ->liteError (sprintf ('Not enough arguments (missing: "%s"). ' , implode (', ' , $ missingArgs )));
215+ return false ;
216+ }
217+
218+ $ index = 0 ;
219+ $ args = [];
220+
221+ foreach ($ defArgs as $ name => $ conf ) {
222+ $ args [$ name ] = $ givenArgs [$ index ] ?? $ conf ['default ' ];
223+ $ index ++;
224+ }
225+
226+ $ in ->setArgs ($ args );
227+
228+ // check options
229+ $ opts = $ missingOpts = [];
230+ $ givenLOpts = $ in ->getLongOpts ();
231+ $ defOpts = $ def ->getOptions ();
232+
233+ foreach ($ defOpts as $ name => $ conf ) {
234+ if (!$ in ->hasLOpt ($ name )) {
235+ if (($ srt = $ conf ['shortcut ' ]) && $ in ->hasSOpt ($ srt )) {
236+ $ opts [$ name ] = $ in ->sOpt ($ srt );
237+ } elseif ($ conf ['required ' ]) {
238+ $ missingOpts [] = "-- {$ name }" . ($ srt ? "|- {$ srt }" : '' );
239+ }
240+ }
241+ }
242+
243+ if (count ($ missingOpts ) > 0 ) {
244+ $ this ->output ->liteError (sprintf ('Not enough options parameters (missing: "%s"). ' , implode (', ' , $ missingOpts )));
245+
246+ return false ;
247+ }
248+
249+ return true ;
181250 }
182251
183252 /**
0 commit comments