@@ -61,6 +61,71 @@ public function register($command)
6161 return $ command ;
6262 }
6363
64+ protected function normalizeCommandInput (string $ input ): array
65+ {
66+ $ tokens = preg_split ('/\s+/ ' , trim ($ input ));
67+ $ result = [
68+ 'command ' => null ,
69+ 'args ' => [],
70+ 'options ' => []
71+ ];
72+
73+ $ i = 0 ;
74+ $ len = count ($ tokens );
75+
76+ if ($ len > 0 ) {
77+ $ result ['command ' ] = $ tokens [$ i ++];
78+ }
79+
80+ while ($ i < $ len ) {
81+ $ token = $ tokens [$ i ];
82+
83+ // Long option: --option or --option=value
84+ if (strpos ($ token , '-- ' ) === 0 ) {
85+ $ option = substr ($ token , 2 );
86+ if (strpos ($ option , '= ' ) !== false ) {
87+ [$ name , $ value ] = explode ('= ' , $ option , 2 );
88+ $ result ['options ' ][$ name ] = strpos ($ value , ', ' ) !== false ? explode (', ' , $ value ) : $ value ;
89+ } elseif (isset ($ tokens [$ i + 1 ]) && strpos ($ tokens [$ i + 1 ], '- ' ) !== 0 ) {
90+ // --option value
91+ $ value = [];
92+ while (isset ($ tokens [$ i + 1 ]) && strpos ($ tokens [$ i + 1 ], '- ' ) !== 0 ) {
93+ $ value [] = $ tokens [++$ i ];
94+ }
95+ $ result ['options ' ][$ option ] = count ($ value ) === 1 ? $ value [0 ] : $ value ;
96+ } else {
97+ // --option (boolean true)
98+ $ result ['options ' ][$ option ] = true ;
99+ }
100+ }
101+
102+ // Short option: -a or -abc or -k value
103+ elseif (strpos ($ token , '- ' ) === 0 && strlen ($ token ) > 1 ) {
104+ $ flags = substr ($ token , 1 );
105+
106+ // Handle -k value
107+ if (strlen ($ flags ) === 1 && isset ($ tokens [$ i + 1 ]) && strpos ($ tokens [$ i + 1 ], '- ' ) !== 0 ) {
108+ $ result ['options ' ][$ flags ] = $ tokens [++$ i ];
109+ } else {
110+ // Handle -abc => a=true, b=true, c=true
111+ foreach (str_split ($ flags ) as $ flag ) {
112+ $ result ['options ' ][$ flag ] = true ;
113+ }
114+ }
115+ }
116+
117+ // Normal argument
118+ else {
119+ $ result ['args ' ][] = $ token ;
120+ }
121+
122+ $ i ++;
123+ }
124+
125+ return $ result ;
126+ }
127+
128+
64129 /**
65130 * Run your sprout app
66131 * @return void
@@ -71,7 +136,10 @@ public function run()
71136 $ arguments = [];
72137
73138 $ argv = (array ) $ _SERVER ['argv ' ];
139+
74140 $ commandName = $ argv [1 ] ?? '' ;
141+ $ commandString = join (' ' , array_slice ($ argv , 1 ));
142+ $ commandData = $ this ->normalizeCommandInput ($ commandString );
75143
76144 if ($ commandName === '' || $ commandName === 'list ' ) {
77145 $ this ->renderListView ();
@@ -84,38 +152,27 @@ public function run()
84152 }
85153
86154 $ command = $ this ->config ['commands ' ][$ commandName ]['handler ' ];
87- $ argumentNames = $ this ->config ['commands ' ][$ commandName ]['arguments ' ];
88-
89- foreach (array_slice ($ argv , 2 ) as $ arg ) {
90- $ parts = explode ('= ' , $ arg );
91-
92- if (strpos ($ parts [0 ], '- ' ) === 0 && strpos ($ parts [0 ], '-- ' ) === false ) {
93- $ paramName = array_filter ($ command ->getHelp ()['params ' ], function ($ param ) use ($ parts ) {
94- return $ param ['short ' ] === ltrim ($ parts [0 ], '- ' );
95- });
96155
97- if (!empty ($ paramName )) {
98- $ parts [0 ] = '-- ' . (array_values ($ paramName )[0 ]['long ' ]);
99- }
100- }
101-
102- if (count ($ parts ) >= 2 ) {
103- $ params [substr ($ parts [0 ], 2 )] = join ('= ' , array_slice ($ parts , 1 ));
104- continue ;
105- }
156+ foreach (array_values ($ command ->getHelp ()['params ' ]) as $ paramData ) {
157+ $ params [$ paramData ['long ' ]] = (
158+ isset ($ commandData ['options ' ][$ paramData ['long ' ]]) ||
159+ isset ($ commandData ['options ' ][$ paramData ['short ' ]])
160+ ) ?
161+ ($ commandData ['options ' ][$ paramData ['long ' ]] ?? $ commandData ['options ' ][$ paramData ['short ' ]] ?? null ) :
162+ $ paramData ['default ' ] ?? null ;
106163
107- if (strpos ($ parts [0 ], '-- ' ) === 0 ) {
108- $ params [substr ($ parts [0 ], 2 )] = true ;
109- continue ;
164+ if ($ paramData ['optional ' ] === false && $ params [$ paramData ['long ' ]] === null ) {
165+ die ("Argument -- {$ paramData ['long ' ]} is required \n" );
110166 }
167+ }
111168
112- while (null !== ($ part = array_shift ($ argumentNames ))) {
113- $ part = str_replace (['{ ' , '} ' ], '' , $ part );
114-
115- $ arguments [$ part ] = $ arg ;
116-
169+ foreach ($ this ->config ['commands ' ][$ commandName ]['arguments ' ] as $ index => $ arg ) {
170+ if ($ command ->getHelp ()['arguments ' ][$ arg ]['type ' ] ?? null === 'array ' ) {
171+ $ arguments [$ arg ] = array_slice ($ commandData ['args ' ], $ index );
117172 break ;
118173 }
174+
175+ $ arguments [$ arg ] = $ commandData ['args ' ][$ index ] ?? null ;
119176 }
120177
121178 $ command ->setParams ($ params );
0 commit comments