From dd004e880fa0a4b72072c2e4bb5d49d4e0a78975 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sat, 28 Oct 2023 10:52:22 +0900 Subject: [PATCH] feat: add `config:check` command to check Config vaules --- system/Commands/Utilities/ConfigCheck.php | 146 +++++++++++++ .../Commands/Utilities/ConfigCheckTest.php | 205 ++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100644 system/Commands/Utilities/ConfigCheck.php create mode 100644 tests/system/Commands/Utilities/ConfigCheckTest.php diff --git a/system/Commands/Utilities/ConfigCheck.php b/system/Commands/Utilities/ConfigCheck.php new file mode 100644 index 000000000000..3a9abf821b0a --- /dev/null +++ b/system/Commands/Utilities/ConfigCheck.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Commands\Utilities; + +use CodeIgniter\CLI\BaseCommand; +use CodeIgniter\CLI\CLI; +use CodeIgniter\Config\BaseConfig; +use Kint\Kint; + +/** + * Check the Config values. + * + * @see \CodeIgniter\Commands\Utilities\ConfigCheckTest + */ +final class ConfigCheck extends BaseCommand +{ + /** + * The group the command is lumped under + * when listing commands. + * + * @var string + */ + protected $group = 'CodeIgniter'; + + /** + * The Command's name + * + * @var string + */ + protected $name = 'config:check'; + + /** + * The Command's short description + * + * @var string + */ + protected $description = 'Check your Config values.'; + + /** + * The Command's usage + * + * @var string + */ + protected $usage = 'config:check '; + + /** + * The Command's arguments + * + * @var array + */ + protected $arguments = [ + 'classname' => 'The config classname to check. Short classname or FQCN.', + ]; + + /** + * The Command's options + * + * @var array + */ + protected $options = []; + + /** + * {@inheritDoc} + */ + public function run(array $params) + { + if (! isset($params[0])) { + CLI::error('You must specify a Config classname.'); + CLI::write(' Usage: ' . $this->usage); + CLI::write('Example: config:check App'); + CLI::write(' config:check \'CodeIgniter\Shield\Config\Auth\''); + + return EXIT_ERROR; + } + + /** @var class-string $class */ + $class = $params[0]; + + $config = config($class); + + if ($config === null) { + CLI::error('No such Config class: ' . $class); + + return EXIT_ERROR; + } + + if (defined('KINT_DIR') && Kint::$enabled_mode !== false) { + CLI::write($this->getKintD($config)); + } else { + CLI::write( + CLI::color($this->getVarDump($config), 'cyan') + ); + } + + return EXIT_SUCCESS; + } + + /** + * Gets object dump by Kint d() + */ + private function getKintD(object $config): string + { + ob_start(); + d($config); + $output = ob_get_clean(); + + $output = trim($output); + $output = preg_replace( + '/\x1b\[36m.*┘\x1b\[0m/su', + '', + $output + ); + $output = preg_replace( + '/\x1b\[36m.*Called from .*\x1b\[0m/su', + '', + $output + ); + + return trim($output); + } + + /** + * Gets object dump by var_dump() + */ + private function getVarDump(object $config): string + { + ob_start(); + var_dump($config); + $output = ob_get_clean(); + + return preg_replace( + '!.*system/Commands/Utilities/ConfigCheck.php.*\n!u', + '', + $output + ); + } +} diff --git a/tests/system/Commands/Utilities/ConfigCheckTest.php b/tests/system/Commands/Utilities/ConfigCheckTest.php new file mode 100644 index 000000000000..bbf69f00a9d0 --- /dev/null +++ b/tests/system/Commands/Utilities/ConfigCheckTest.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Commands\Utilities; + +use CodeIgniter\Test\CIUnitTestCase; +use CodeIgniter\Test\StreamFilterTrait; +use Config\App; +use Config\Services; + +/** + * @internal + * + * @group Others + */ +final class ConfigCheckTest extends CIUnitTestCase +{ + use StreamFilterTrait; + + protected function setUp(): void + { + $this->resetServices(); + parent::setUp(); + } + + protected function tearDown(): void + { + $this->resetServices(); + parent::tearDown(); + } + + protected function getBuffer() + { + return $this->getStreamFilterBuffer(); + } + + public function testCommandConfigCheckNoArg(): void + { + command('config:check'); + + $this->assertStringContainsString( + 'You must specify a Config classname.', + $this->getBuffer() + ); + } + + public function testCommandConfigCheckApp(): void + { + command('config:check App'); + + $this->assertStringContainsString(App::class, $this->getBuffer()); + $this->assertStringContainsString("public 'baseURL", $this->getBuffer()); + } + + public function testCommandConfigCheckNonexistentClass(): void + { + command('config:check Nonexistent'); + + $this->assertStringContainsString( + 'No such Config class: Nonexistent', + $this->getBuffer() + ); + } + + public function testGetKintD() + { + $command = new ConfigCheck(Services::logger(), Services::commands()); + $getKintD = $this->getPrivateMethodInvoker($command, 'getKintD'); + + $output = $getKintD(new App()); + + $output = preg_replace( + '/(\033\[[0-9;]+m)|(\035\[[0-9;]+m)/u', + '', + $output + ); + + $this->assertStringContainsString( + 'Config\App#', + $output + ); + $this->assertStringContainsString( + <<<'EOL' + ( + public 'baseURL' -> string (19) "http://example.com/" + public 'allowedHostnames' -> array (0) [] + public 'indexPage' -> string (9) "index.php" + public 'uriProtocol' -> string (11) "REQUEST_URI" + public 'defaultLocale' -> string (2) "en" + public 'negotiateLocale' -> boolean false + public 'supportedLocales' -> array (1) [ + 0 => string (2) "en" + ] + public 'appTimezone' -> string (3) "UTC" + public 'charset' -> string (5) "UTF-8" + public 'forceGlobalSecureRequests' -> boolean false + public 'proxyIPs' -> array (0) [] + public 'CSPEnabled' -> boolean false + EOL, + $output + ); + } + + public function testGetVarDump() + { + $command = new ConfigCheck(Services::logger(), Services::commands()); + $getVarDump = $this->getPrivateMethodInvoker($command, 'getVarDump'); + + $output = $getVarDump(new App()); + + if (function_exists('xdebug_get_headers')) { + // Xdebug is enabled. + $this->assertStringContainsString( + 'class Config\App#', + $output + ); + $this->assertStringContainsString( + <<<'EOL' + { + public string $baseURL => + string(19) "http://example.com/" + public array $allowedHostnames => + array(0) { + } + public string $indexPage => + string(9) "index.php" + public string $uriProtocol => + string(11) "REQUEST_URI" + public string $defaultLocale => + string(2) "en" + public bool $negotiateLocale => + bool(false) + public array $supportedLocales => + array(1) { + [0] => + string(2) "en" + } + public string $appTimezone => + string(3) "UTC" + public string $charset => + string(5) "UTF-8" + public bool $forceGlobalSecureRequests => + bool(false) + public array $proxyIPs => + array(0) { + } + public bool $CSPEnabled => + bool(false) + } + EOL, + $output + ); + } else { + // Xdebug is disabled. + $this->assertStringContainsString( + 'object(Config\App)#', + $output + ); + $this->assertStringContainsString( + <<<'EOL' + { + ["baseURL"]=> + string(19) "http://example.com/" + ["allowedHostnames"]=> + array(0) { + } + ["indexPage"]=> + string(9) "index.php" + ["uriProtocol"]=> + string(11) "REQUEST_URI" + ["defaultLocale"]=> + string(2) "en" + ["negotiateLocale"]=> + bool(false) + ["supportedLocales"]=> + array(1) { + [0]=> + string(2) "en" + } + ["appTimezone"]=> + string(3) "UTC" + ["charset"]=> + string(5) "UTF-8" + ["forceGlobalSecureRequests"]=> + bool(false) + ["proxyIPs"]=> + array(0) { + } + ["CSPEnabled"]=> + bool(false) + } + EOL, + $output + ); + } + } +}