diff --git a/system/Commands/Generators/ConfigGenerator.php b/system/Commands/Generators/ConfigGenerator.php index e62abbe69f4a..8c78e5ae1dda 100644 --- a/system/Commands/Generators/ConfigGenerator.php +++ b/system/Commands/Generators/ConfigGenerator.php @@ -13,90 +13,31 @@ namespace CodeIgniter\Commands\Generators; -use CodeIgniter\CLI\BaseCommand; -use CodeIgniter\CLI\GeneratorTrait; - -/** - * Generates a skeleton config file. - */ -class ConfigGenerator extends BaseCommand +use CodeIgniter\CLI\AbstractGeneratorCommand; +use CodeIgniter\CLI\Attributes\Command; +use CodeIgniter\CLI\Attributes\GeneratorCommand; + +#[Command(name: 'make:config', description: 'Generates a new config file.', group: 'Generators')] +#[GeneratorCommand( + component: 'Config', + template: 'config.tpl.php', + directory: 'Config', + classNameLang: 'CLI.generator.className.config', +)] +class ConfigGenerator extends AbstractGeneratorCommand { - use GeneratorTrait; - - /** - * The Command's Group - * - * @var string - */ - protected $group = 'Generators'; - - /** - * The Command's Name - * - * @var string - */ - protected $name = 'make:config'; - - /** - * The Command's Description - * - * @var string - */ - protected $description = 'Generates a new config file.'; - - /** - * The Command's Usage - * - * @var string - */ - protected $usage = 'make:config [options]'; - - /** - * The Command's Arguments - * - * @var array - */ - protected $arguments = [ - 'name' => 'The config class name.', - ]; - - /** - * The Command's Options - * - * @var array - */ - protected $options = [ - '--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".', - '--suffix' => 'Append the component title to the class name (e.g. User => UserConfig).', - '--force' => 'Force overwrite existing file.', - ]; - - /** - * Actually execute a command. - */ - public function run(array $params) + protected function getReplacements(string $class): array { - $this->component = 'Config'; - $this->directory = 'Config'; - $this->template = 'config.tpl.php'; - - $this->classNameLang = 'CLI.generator.className.config'; - $this->generateClass($params); + $segments = explode('\\', $class); + array_pop($segments); - return EXIT_SUCCESS; - } - - /** - * Prepare options and do the necessary replacements. - */ - protected function prepare(string $class): string - { - $namespace = $this->getOption('namespace') ?? APP_NAMESPACE; + $namespace = implode('\\', $segments); + $prefix = APP_NAMESPACE . '\\'; - if ($namespace === APP_NAMESPACE) { - $class = substr($class, strlen($namespace . '\\')); + if (! str_starts_with($namespace, $prefix)) { + return []; } - return $this->parseTemplate($class); + return ['{namespace}' => substr($namespace, strlen($prefix))]; } } diff --git a/tests/system/Commands/Generators/ConfigGeneratorTest.php b/tests/system/Commands/Generators/ConfigGeneratorTest.php index 473efff9a3a0..4418f7cf5870 100644 --- a/tests/system/Commands/Generators/ConfigGeneratorTest.php +++ b/tests/system/Commands/Generators/ConfigGeneratorTest.php @@ -13,6 +13,7 @@ namespace CodeIgniter\Commands\Generators; +use CodeIgniter\CLI\CLI; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\StreamFilterTrait; use PHPUnit\Framework\Attributes\Group; @@ -25,24 +26,78 @@ final class ConfigGeneratorTest extends CIUnitTestCase { use StreamFilterTrait; + protected function setUp(): void + { + parent::setUp(); + + CLI::reset(); + } + protected function tearDown(): void { - $result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', $this->getStreamFilterBuffer()); - $file = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14))); - if (is_file($file)) { - unlink($file); + parent::tearDown(); + + CLI::reset(); + + foreach (['Auth.php', 'AuthConfig.php'] as $file) { + if (is_file(APPPATH . 'Config/' . $file)) { + unlink(APPPATH . 'Config/' . $file); + } } + + if (is_dir(APPPATH . 'Config/Sub')) { + helper('filesystem'); + delete_files(APPPATH . 'Config/Sub', true); + rmdir(APPPATH . 'Config/Sub'); + } + + if (is_file(SUPPORTPATH . 'Config/Auth.php')) { + unlink(SUPPORTPATH . 'Config/Auth.php'); + } + } + + private function getUndecoratedBuffer(): string + { + return preg_replace('/\e\[[^m]+m/', '', $this->getStreamFilterBuffer()) ?? ''; } public function testGenerateConfig(): void { command('make:config auth'); - $this->assertFileExists(APPPATH . 'Config/Auth.php'); + + $this->assertSame( + PHP_EOL . 'File created: ' . clean_path(APPPATH . 'Config/Auth.php') . PHP_EOL, + $this->getUndecoratedBuffer(), + ); + + $content = file_get_contents(APPPATH . 'Config/Auth.php'); + $this->assertIsString($content); + $this->assertStringContainsString('namespace Config;', $content); + $this->assertStringContainsString('class Auth extends BaseConfig', $content); + } + + public function testGenerateConfigInSubdirectory(): void + { + command('make:config sub/auth'); + + $content = file_get_contents(APPPATH . 'Config/Sub/Auth.php'); + $this->assertIsString($content); + $this->assertStringContainsString('namespace Config\\Sub;', $content); + } + + public function testGenerateConfigWithOtherNamespaceKeepsFullNamespace(): void + { + command('make:config auth --namespace Tests\\\\Support'); + + $content = file_get_contents(SUPPORTPATH . 'Config/Auth.php'); + $this->assertIsString($content); + $this->assertStringContainsString('namespace Tests\\Support\\Config;', $content); } - public function testGenerateConfigWithOptionSuffix(): void + public function testGenerateConfigWithSuffix(): void { - command('make:config auth -suffix'); + command('make:config auth --suffix'); + $this->assertFileExists(APPPATH . 'Config/AuthConfig.php'); } } diff --git a/user_guide_src/source/cli/cli_generators.rst b/user_guide_src/source/cli/cli_generators.rst index 80634f8867dd..c132a5964e36 100644 --- a/user_guide_src/source/cli/cli_generators.rst +++ b/user_guide_src/source/cli/cli_generators.rst @@ -108,9 +108,9 @@ Argument: Options: ======== -* ``--namespace``: Set the root namespace. Defaults to value of ``APP_NAMESPACE``. -* ``--suffix``: Append the component suffix to the generated class name. -* ``--force``: Set this flag to overwrite existing files on destination. +* ``--namespace`` (``-n``): Set the root namespace. Defaults to value of ``APP_NAMESPACE``. +* ``--suffix`` (``-s``): Append the component suffix to the generated class name. +* ``--force`` (``-f``): Set this flag to overwrite existing files on destination. make:controller ---------------