Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions system/Autoloader/FileLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,6 @@ protected function getNamespaces()
return array_merge($namespaces, $system);
}

/**
* Find the qualified name of a file according to
* the namespace of the first matched namespace path.
*
* @return false|string The qualified name or false if the path is not found
*/
public function findQualifiedNameFromPath(string $path)
{
$resolvedPath = realpath($path);
Expand Down Expand Up @@ -299,7 +293,9 @@ public function findQualifiedNameFromPath(string $path)
),
'\\',
);

// Remove the file extension (.php)
/** @var class-string */
$className = mb_substr($className, 0, -4);

if (in_array($className, $this->invalidClassnames, true)) {
Expand Down
2 changes: 1 addition & 1 deletion system/Autoloader/FileLocatorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp =
* Find the qualified name of a file according to
* the namespace of the first matched namespace path.
*
* @return false|string The qualified name or false if the path is not found
* @return class-string|false The qualified name or false if the path is not found
*/
public function findQualifiedNameFromPath(string $path);

Expand Down
8 changes: 6 additions & 2 deletions system/CLI/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ class CLI
/**
* List of array segments.
*
* @var array
* @var list<string>
*/
protected static $segments = [];

/**
* @var array
* @var array<string, string|null>
*/
protected static $options = [];

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

/**
* Returns the raw array of segments found.
*
* @return list<string>
*/
public static function getSegments(): array
{
Expand Down Expand Up @@ -971,6 +973,8 @@ public static function getOption(string $name)

/**
* Returns the raw array of options found.
*
* @return array<string, string|null>
*/
public static function getOptions(): array
{
Expand Down
24 changes: 18 additions & 6 deletions system/CLI/Commands.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@

/**
* Core functionality for running, listing, etc commands.
*
* @phpstan-type commands_list array<string, array{'class': class-string<BaseCommand>, 'file': string, 'group': string,'description': string}>
*/
class Commands
{
/**
* The found commands.
*
* @var array
* @var commands_list
*/
protected $commands = [];

Expand All @@ -52,6 +54,8 @@ public function __construct($logger = null)
/**
* Runs a command given
*
* @param array<int|string, string|null> $params
*
* @return int Exit code
*/
public function run(string $command, array $params)
Expand All @@ -77,7 +81,7 @@ public function run(string $command, array $params)
/**
* Provide access to the list of commands.
*
* @return array
* @return commands_list
*/
public function getCommands()
{
Expand All @@ -96,7 +100,7 @@ public function discoverCommands()
return;
}

/** @var FileLocatorInterface $locator */
/** @var FileLocatorInterface */
$locator = service('locator');
$files = $locator->listFiles('Commands/');

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

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

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

if (isset($class->group) && ! isset($this->commands[$class->name])) {
Expand All @@ -146,16 +150,18 @@ public function discoverCommands()
/**
* Verifies if the command being sought is found
* in the commands list.
*
* @param commands_list $commands
*/
public function verifyCommand(string $command, array $commands): bool
{
if (isset($commands[$command])) {
return true;
}

$message = lang('CLI.commandNotFound', [$command]);

$message = lang('CLI.commandNotFound', [$command]);
$alternatives = $this->getCommandAlternatives($command, $commands);

if ($alternatives !== []) {
if (count($alternatives) === 1) {
$message .= "\n\n" . lang('CLI.altCommandSingular') . "\n ";
Expand All @@ -175,11 +181,17 @@ public function verifyCommand(string $command, array $commands): bool
/**
* Finds alternative of `$name` among collection
* of commands.
*
* @param commands_list $collection
*
* @return list<string>
*/
protected function getCommandAlternatives(string $name, array $collection): array
{
/** @var array<string, int> */
$alternatives = [];

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

Expand Down
7 changes: 4 additions & 3 deletions system/CLI/Console.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ public function run()
$appConfig = config(App::class);
Services::createRequest($appConfig, true);
// Load Routes
Services::routes()->loadRoutes();
service('routes')->loadRoutes();

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

return $runner->run($command, $params);
return service('commands')->run($command, $params);
}

/**
Expand Down Expand Up @@ -75,6 +74,8 @@ public function showHeader(bool $suppress = false)
* If present, it will be found as `['help' => null]`.
* We'll remove that as an option from `$params` and
* unshift it as argument instead.
*
* @param array<int|string, string|null> $params
*/
private function parseParamsForHelpOption(array $params): array
{
Expand Down
6 changes: 3 additions & 3 deletions system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ function clean_path(string $path): string
*/
function command(string $command)
{
$runner = service('commands');
$regexString = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
$regexQuoted = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';

Expand Down Expand Up @@ -156,8 +155,9 @@ function command(string $command)
$cursor += strlen($match[0]);
}

$command = array_shift($args);
/** @var array<int|string, string|null> */
$params = [];
$command = array_shift($args);
$optionValue = false;

foreach ($args as $i => $arg) {
Expand Down Expand Up @@ -187,7 +187,7 @@ function command(string $command)
}

ob_start();
$runner->run($command, $params);
service('commands')->run($command, $params);

return ob_get_clean();
}
Expand Down
2 changes: 2 additions & 0 deletions system/Config/BaseConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Config;

use CodeIgniter\Autoloader\FileLocatorInterface;
use CodeIgniter\Exceptions\ConfigException;
use CodeIgniter\Exceptions\RuntimeException;
use Config\Encryption;
Expand Down Expand Up @@ -252,6 +253,7 @@ protected function registerProperties()

static::$discovering = true;

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

Expand Down
2 changes: 2 additions & 0 deletions system/Config/Factories.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace CodeIgniter\Config;

use CodeIgniter\Autoloader\FileLocatorInterface;
use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Exceptions\InvalidArgumentException;
use CodeIgniter\Model;
Expand Down Expand Up @@ -299,6 +300,7 @@ class_exists($alias, false)
}

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

// Check if the class alias was namespaced
Expand Down
3 changes: 2 additions & 1 deletion system/Publisher/Publisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ final public static function discover(string $directory = 'Publishers', string $

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

/** @var FileLocatorInterface $locator */
/** @var FileLocatorInterface */
$locator = service('locator');

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

if ($className !== false && class_exists($className) && is_a($className, self::class, true)) {
/** @var class-string<self> $className */
self::$discovered[$key][] = new $className();
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/system/CLI/CLITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ public function testParseCommandMultipleOptions(): void

$this->assertSame(['parm' => 'pvalue', 'p2' => null, 'p3' => 'value 3'], CLI::getOptions());
$this->assertSame('pvalue', CLI::getOption('parm'));
$this->assertTrue(CLI::getOption('p2'));
$this->assertSame('-parm pvalue -p2 -p3 "value 3" ', CLI::getOptionString());
$this->assertSame('-parm pvalue -p2 -p3 "value 3"', CLI::getOptionString(false, true));
$this->assertSame('--parm pvalue --p2 --p3 "value 3" ', CLI::getOptionString(true));
Expand Down
2 changes: 1 addition & 1 deletion tests/system/CLI/ConsoleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function testHelpArgumentAndHelpOptionCombined(): void
}

/**
* @param array $command
* @param string ...$command
*/
protected function initCLI(...$command): void
{
Expand Down
11 changes: 9 additions & 2 deletions tests/system/Commands/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use CodeIgniter\Test\StreamFilterTrait;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Tests\Support\Commands\AppInfo;
use Tests\Support\Commands\ParamsReveal;

/**
Expand Down Expand Up @@ -74,19 +75,25 @@ public function testShowError(): void
{
command('app:info');
$commands = $this->commands->getCommands();
$command = new $commands['app:info']['class']($this->logger, $this->commands);

/** @var AppInfo */
$command = new $commands['app:info']['class']($this->logger, $this->commands);

$command->helpme();

$this->assertStringContainsString('Displays basic usage information.', $this->getBuffer());
}

public function testCommandCall(): void
{
command('app:info');
$commands = $this->commands->getCommands();
$command = new $commands['app:info']['class']($this->logger, $this->commands);

/** @var AppInfo */
$command = new $commands['app:info']['class']($this->logger, $this->commands);

$command->bomb();

$this->assertStringContainsString('Invalid "background" color:', $this->getBuffer());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ parameters:
path: ../../tests/system/CLI/ConsoleTest.php

-
message: '#^Assigning non\-empty\-array\<int\|string, ''spark''\|array\> directly on offset ''argv'' of \$_SERVER is discouraged\.$#'
message: '#^Assigning non\-empty\-array\<int\|string, string\> directly on offset ''argv'' of \$_SERVER is discouraged\.$#'
count: 1
path: ../../tests/system/CLI/ConsoleTest.php

Expand Down
Loading
Loading