diff --git a/src/Illuminate/Foundation/Console/ConfigShowCommand.php b/src/Illuminate/Foundation/Console/ConfigShowCommand.php new file mode 100644 index 000000000000..8819c457da6b --- /dev/null +++ b/src/Illuminate/Foundation/Console/ConfigShowCommand.php @@ -0,0 +1,125 @@ +argument('config'); + + $data = config($config); + + if (! $data) { + $this->components->error("Configuration file `{$config}` does not exist."); + + return Command::FAILURE; + } + + $this->newLine(); + $this->render($config, $data); + $this->newLine(); + + return Command::SUCCESS; + } + + /** + * Render the configuration values. + * + * @param string $name + * @param mixed $data + * @return void + */ + public function render($name, $data) + { + if (! is_array($data)) { + $this->title($name, $this->formatValue($data)); + + return; + } + + $this->title($name); + + foreach (Arr::dot($data) as $key => $value) { + $this->components->twoColumnDetail( + $this->formatKey($key), + $this->formatValue($value) + ); + } + } + + /** + * Render the title. + * + * @param string $title + * @param string|null $subtitle + * @return void + */ + public function title($title, $subtitle = null) + { + $this->components->twoColumnDetail( + "{$title}", + $subtitle, + ); + } + + /** + * Format the given configuration key. + * + * @param string $key + * @return string + */ + protected function formatKey($key) + { + return preg_replace_callback( + '/(.*)\.(.*)$/', fn ($matches) => sprintf( + '%s ⇁ %s', + str_replace('.', ' ⇁ ', $matches[1]), + $matches[2] + ), $key + ); + } + + /** + * Format the given configuration value. + * + * @param mixed $value + * @return string + */ + protected function formatValue($value) + { + return match (true) { + is_bool($value) => sprintf('%s', $value ? 'true' : 'false'), + is_null($value) => 'null', + is_numeric($value) => "{$value}", + is_array($value) => '[]', + is_object($value) => get_class($value), + is_string($value) => $value, + default => print_r($value, true), + }; + } +} diff --git a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php index 7d756ced01a6..f78472a98b32 100755 --- a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php @@ -35,6 +35,7 @@ use Illuminate\Foundation\Console\ComponentMakeCommand; use Illuminate\Foundation\Console\ConfigCacheCommand; use Illuminate\Foundation\Console\ConfigClearCommand; +use Illuminate\Foundation\Console\ConfigShowCommand; use Illuminate\Foundation\Console\ConsoleMakeCommand; use Illuminate\Foundation\Console\DocsCommand; use Illuminate\Foundation\Console\DownCommand; @@ -111,6 +112,7 @@ class ArtisanServiceProvider extends ServiceProvider implements DeferrableProvid 'ClearResets' => ClearResetsCommand::class, 'ConfigCache' => ConfigCacheCommand::class, 'ConfigClear' => ConfigClearCommand::class, + 'ConfigShow' => ConfigShowCommand::class, 'Db' => DbCommand::class, 'DbMonitor' => DatabaseMonitorCommand::class, 'DbPrune' => PruneCommand::class, diff --git a/tests/Testing/Console/ConfigShowCommandTest.php b/tests/Testing/Console/ConfigShowCommandTest.php new file mode 100644 index 000000000000..5f77c29ecb46 --- /dev/null +++ b/tests/Testing/Console/ConfigShowCommandTest.php @@ -0,0 +1,75 @@ +set('test', [ + 'string' => 'Test', + 'int' => 1, + 'float' => 1.2, + 'boolean' => true, + 'null' => null, + 'array' => [ + ConfigShowCommand::class, + ], + 'empty_array' => [], + 'assoc_array' => ['foo' => 'bar'], + 'class' => new \stdClass, + ]); + + $this->artisan(ConfigShowCommand::class, ['config' => 'test']) + ->assertSuccessful() + ->expectsOutput(' test ....................................................... ') + ->expectsOutput(' string ................................................ Test ') + ->expectsOutput(' int ...................................................... 1 ') + ->expectsOutput(' float .................................................. 1.2 ') + ->expectsOutput(' boolean ............................................... true ') + ->expectsOutput(' null .................................................. null ') + ->expectsOutput(' array ⇁ 0 .. Illuminate\Foundation\Console\ConfigShowCommand ') + ->expectsOutput(' empty_array ............................................. [] ') + ->expectsOutput(' assoc_array ⇁ foo ...................................... bar ') + ->expectsOutput(' class ............................................. stdClass '); + } + + public function testDisplayNestedConfigItems() + { + config()->set('test', [ + 'nested' => [ + 'foo' => 'bar', + ], + ]); + + $this->artisan(ConfigShowCommand::class, ['config' => 'test.nested']) + ->assertSuccessful() + ->expectsOutput(' test.nested ................................................ ') + ->expectsOutput(' foo .................................................... bar '); + } + + public function testDisplaySingleValue() + { + config()->set('foo', 'bar'); + + $this->artisan(ConfigShowCommand::class, ['config' => 'foo']) + ->assertSuccessful() + ->expectsOutput(' foo .................................................... bar '); + } + + public function testDisplayErrorIfConfigDoesNotExist() + { + $this->artisan(ConfigShowCommand::class, ['config' => 'invalid']) + ->assertFailed(); + } +}