Skip to content

Commit 0e0a5ad

Browse files
authored
refactor: Typing commands (#9488)
* refactor: Improve typing in the Command area * tests: Check the case when CLI option is `null` * chore: Update phpstan baseline
1 parent 9b9d427 commit 0e0a5ad

File tree

14 files changed

+53
-87
lines changed

14 files changed

+53
-87
lines changed

system/Autoloader/FileLocator.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,6 @@ protected function getNamespaces()
266266
return array_merge($namespaces, $system);
267267
}
268268

269-
/**
270-
* Find the qualified name of a file according to
271-
* the namespace of the first matched namespace path.
272-
*
273-
* @return false|string The qualified name or false if the path is not found
274-
*/
275269
public function findQualifiedNameFromPath(string $path)
276270
{
277271
$resolvedPath = realpath($path);
@@ -299,7 +293,9 @@ public function findQualifiedNameFromPath(string $path)
299293
),
300294
'\\',
301295
);
296+
302297
// Remove the file extension (.php)
298+
/** @var class-string */
303299
$className = mb_substr($className, 0, -4);
304300

305301
if (in_array($className, $this->invalidClassnames, true)) {

system/Autoloader/FileLocatorInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp =
6262
* Find the qualified name of a file according to
6363
* the namespace of the first matched namespace path.
6464
*
65-
* @return false|string The qualified name or false if the path is not found
65+
* @return class-string|false The qualified name or false if the path is not found
6666
*/
6767
public function findQualifiedNameFromPath(string $path);
6868

system/CLI/CLI.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ class CLI
107107
/**
108108
* List of array segments.
109109
*
110-
* @var array
110+
* @var list<string>
111111
*/
112112
protected static $segments = [];
113113

114114
/**
115-
* @var array
115+
* @var array<string, string|null>
116116
*/
117117
protected static $options = [];
118118

@@ -944,6 +944,8 @@ public static function getSegment(int $index)
944944

945945
/**
946946
* Returns the raw array of segments found.
947+
*
948+
* @return list<string>
947949
*/
948950
public static function getSegments(): array
949951
{
@@ -971,6 +973,8 @@ public static function getOption(string $name)
971973

972974
/**
973975
* Returns the raw array of options found.
976+
*
977+
* @return array<string, string|null>
974978
*/
975979
public static function getOptions(): array
976980
{

system/CLI/Commands.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121

2222
/**
2323
* Core functionality for running, listing, etc commands.
24+
*
25+
* @phpstan-type commands_list array<string, array{'class': class-string<BaseCommand>, 'file': string, 'group': string,'description': string}>
2426
*/
2527
class Commands
2628
{
2729
/**
2830
* The found commands.
2931
*
30-
* @var array
32+
* @var commands_list
3133
*/
3234
protected $commands = [];
3335

@@ -52,6 +54,8 @@ public function __construct($logger = null)
5254
/**
5355
* Runs a command given
5456
*
57+
* @param array<int|string, string|null> $params
58+
*
5559
* @return int Exit code
5660
*/
5761
public function run(string $command, array $params)
@@ -77,7 +81,7 @@ public function run(string $command, array $params)
7781
/**
7882
* Provide access to the list of commands.
7983
*
80-
* @return array
84+
* @return commands_list
8185
*/
8286
public function getCommands()
8387
{
@@ -96,7 +100,7 @@ public function discoverCommands()
96100
return;
97101
}
98102

99-
/** @var FileLocatorInterface $locator */
103+
/** @var FileLocatorInterface */
100104
$locator = service('locator');
101105
$files = $locator->listFiles('Commands/');
102106

@@ -109,6 +113,7 @@ public function discoverCommands()
109113
// Loop over each file checking to see if a command with that
110114
// alias exists in the class.
111115
foreach ($files as $file) {
116+
/** @var class-string<BaseCommand>|false */
112117
$className = $locator->findQualifiedNameFromPath($file);
113118

114119
if ($className === false || ! class_exists($className)) {
@@ -122,7 +127,6 @@ public function discoverCommands()
122127
continue;
123128
}
124129

125-
/** @var BaseCommand $class */
126130
$class = new $className($this->logger, $this);
127131

128132
if (isset($class->group) && ! isset($this->commands[$class->name])) {
@@ -146,16 +150,18 @@ public function discoverCommands()
146150
/**
147151
* Verifies if the command being sought is found
148152
* in the commands list.
153+
*
154+
* @param commands_list $commands
149155
*/
150156
public function verifyCommand(string $command, array $commands): bool
151157
{
152158
if (isset($commands[$command])) {
153159
return true;
154160
}
155161

156-
$message = lang('CLI.commandNotFound', [$command]);
157-
162+
$message = lang('CLI.commandNotFound', [$command]);
158163
$alternatives = $this->getCommandAlternatives($command, $commands);
164+
159165
if ($alternatives !== []) {
160166
if (count($alternatives) === 1) {
161167
$message .= "\n\n" . lang('CLI.altCommandSingular') . "\n ";
@@ -175,11 +181,17 @@ public function verifyCommand(string $command, array $commands): bool
175181
/**
176182
* Finds alternative of `$name` among collection
177183
* of commands.
184+
*
185+
* @param commands_list $collection
186+
*
187+
* @return list<string>
178188
*/
179189
protected function getCommandAlternatives(string $name, array $collection): array
180190
{
191+
/** @var array<string, int> */
181192
$alternatives = [];
182193

194+
/** @var string $commandName */
183195
foreach (array_keys($collection) as $commandName) {
184196
$lev = levenshtein($name, $commandName);
185197

system/CLI/Console.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ public function run()
3838
$appConfig = config(App::class);
3939
Services::createRequest($appConfig, true);
4040
// Load Routes
41-
Services::routes()->loadRoutes();
41+
service('routes')->loadRoutes();
4242

43-
$runner = Services::commands();
4443
$params = array_merge(CLI::getSegments(), CLI::getOptions());
4544
$params = $this->parseParamsForHelpOption($params);
4645
$command = array_shift($params) ?? 'list';
4746

48-
return $runner->run($command, $params);
47+
return service('commands')->run($command, $params);
4948
}
5049

5150
/**
@@ -75,6 +74,8 @@ public function showHeader(bool $suppress = false)
7574
* If present, it will be found as `['help' => null]`.
7675
* We'll remove that as an option from `$params` and
7776
* unshift it as argument instead.
77+
*
78+
* @param array<int|string, string|null> $params
7879
*/
7980
private function parseParamsForHelpOption(array $params): array
8081
{

system/Common.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ function clean_path(string $path): string
124124
*/
125125
function command(string $command)
126126
{
127-
$runner = service('commands');
128127
$regexString = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
129128
$regexQuoted = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
130129

@@ -156,8 +155,9 @@ function command(string $command)
156155
$cursor += strlen($match[0]);
157156
}
158157

159-
$command = array_shift($args);
158+
/** @var array<int|string, string|null> */
160159
$params = [];
160+
$command = array_shift($args);
161161
$optionValue = false;
162162

163163
foreach ($args as $i => $arg) {
@@ -187,7 +187,7 @@ function command(string $command)
187187
}
188188

189189
ob_start();
190-
$runner->run($command, $params);
190+
service('commands')->run($command, $params);
191191

192192
return ob_get_clean();
193193
}

system/Config/BaseConfig.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace CodeIgniter\Config;
1313

14+
use CodeIgniter\Autoloader\FileLocatorInterface;
1415
use CodeIgniter\Exceptions\ConfigException;
1516
use CodeIgniter\Exceptions\RuntimeException;
1617
use Config\Encryption;
@@ -252,6 +253,7 @@ protected function registerProperties()
252253

253254
static::$discovering = true;
254255

256+
/** @var FileLocatorInterface */
255257
$locator = service('locator');
256258
$registrarsFiles = $locator->search('Config/Registrar.php');
257259

system/Config/Factories.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace CodeIgniter\Config;
1515

16+
use CodeIgniter\Autoloader\FileLocatorInterface;
1617
use CodeIgniter\Database\ConnectionInterface;
1718
use CodeIgniter\Exceptions\InvalidArgumentException;
1819
use CodeIgniter\Model;
@@ -299,6 +300,7 @@ class_exists($alias, false)
299300
}
300301

301302
// Have to do this the hard way...
303+
/** @var FileLocatorInterface */
302304
$locator = service('locator');
303305

304306
// Check if the class alias was namespaced

system/Publisher/Publisher.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ final public static function discover(string $directory = 'Publishers', string $
109109

110110
self::$discovered[$key] = [];
111111

112-
/** @var FileLocatorInterface $locator */
112+
/** @var FileLocatorInterface */
113113
$locator = service('locator');
114114

115115
$files = $namespace === ''
@@ -125,6 +125,7 @@ final public static function discover(string $directory = 'Publishers', string $
125125
$className = $locator->findQualifiedNameFromPath($file);
126126

127127
if ($className !== false && class_exists($className) && is_a($className, self::class, true)) {
128+
/** @var class-string<self> $className */
128129
self::$discovered[$key][] = new $className();
129130
}
130131
}

tests/system/CLI/CLITest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ public function testParseCommandMultipleOptions(): void
539539

540540
$this->assertSame(['parm' => 'pvalue', 'p2' => null, 'p3' => 'value 3'], CLI::getOptions());
541541
$this->assertSame('pvalue', CLI::getOption('parm'));
542+
$this->assertTrue(CLI::getOption('p2'));
542543
$this->assertSame('-parm pvalue -p2 -p3 "value 3" ', CLI::getOptionString());
543544
$this->assertSame('-parm pvalue -p2 -p3 "value 3"', CLI::getOptionString(false, true));
544545
$this->assertSame('--parm pvalue --p2 --p3 "value 3" ', CLI::getOptionString(true));

0 commit comments

Comments
 (0)