From 6ca358cef576ae914243b0fa83e4f2c3580bee55 Mon Sep 17 00:00:00 2001 From: ju1ius Date: Wed, 27 Dec 2023 22:41:19 +0100 Subject: [PATCH] uses symfony/console for bin script --- .idea/chicot.iml | 8 ++++ .idea/codeception.xml | 12 ++++++ .idea/php.xml | 13 +++++++ .idea/phpspec.xml | 13 +++++++ .idea/phpunit.xml | 10 +++++ bin/chicot.php | 10 +++-- composer.json | 3 +- src/Cli.php | 28 ------------- src/Command/GenerateStubsCommand.php | 37 ++++++++++++++++++ src/Command/ListExtensionsCommand.php | 27 +++++++++++++ src/Internal/AstBuilder.php | 11 ++++-- tests/Command/GenerateStubsTest.php | 39 +++++++++++++++++++ tests/Command/ListExtensionsTest.php | 18 +++++++++ .../AttributesTest.php} | 5 ++- .../ClassesTest.php} | 5 ++- .../ConstantsTest.php} | 5 ++- .../EnumsTest.php} | 5 ++- .../ExtensionInterfaceTest.php | 3 +- .../FunctionsTest.php} | 5 ++- tests/TemporaryFileGuard.php | 23 +++++++++++ 20 files changed, 234 insertions(+), 46 deletions(-) create mode 100644 .idea/codeception.xml create mode 100644 .idea/phpspec.xml create mode 100644 .idea/phpunit.xml delete mode 100644 src/Cli.php create mode 100644 src/Command/GenerateStubsCommand.php create mode 100644 src/Command/ListExtensionsCommand.php create mode 100644 tests/Command/GenerateStubsTest.php create mode 100644 tests/Command/ListExtensionsTest.php rename tests/{ExtensionAttributesTest.php => Generator/AttributesTest.php} (90%) rename tests/{ExtensionClassTest.php => Generator/ClassesTest.php} (95%) rename tests/{ExtensionConstantsTest.php => Generator/ConstantsTest.php} (87%) rename tests/{ExtensionEnumTest.php => Generator/EnumsTest.php} (92%) rename tests/{ => Generator}/ExtensionInterfaceTest.php (94%) rename tests/{ExtensionFunctionsTest.php => Generator/FunctionsTest.php} (94%) create mode 100644 tests/TemporaryFileGuard.php diff --git a/.idea/chicot.iml b/.idea/chicot.iml index 96a72d8..671d73f 100644 --- a/.idea/chicot.iml +++ b/.idea/chicot.iml @@ -7,6 +7,14 @@ + + + + + + + + diff --git a/.idea/codeception.xml b/.idea/codeception.xml new file mode 100644 index 0000000..330f2dd --- /dev/null +++ b/.idea/codeception.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index 24e28e9..c367c69 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -15,12 +15,25 @@ + + + + + + + + + + + + + diff --git a/.idea/phpspec.xml b/.idea/phpspec.xml new file mode 100644 index 0000000..ec7e1d4 --- /dev/null +++ b/.idea/phpspec.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml new file mode 100644 index 0000000..4f8104c --- /dev/null +++ b/.idea/phpunit.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/bin/chicot.php b/bin/chicot.php index e3d59b8..ca15c87 100644 --- a/bin/chicot.php +++ b/bin/chicot.php @@ -2,7 +2,11 @@ require $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php'; -use Souplette\Chicot\Cli; +use Souplette\Chicot\Command\GenerateStubsCommand; +use Souplette\Chicot\Command\ListExtensionsCommand; +use Symfony\Component\Console\Application; -$app = new Cli(); -exit($app->run($argv)); +$app = new Application('chicot', '0.1.0'); +$app->add(new ListExtensionsCommand('list-extensions')); +$app->add(new GenerateStubsCommand('stub')); +$app->run(); diff --git a/composer.json b/composer.json index 2346ed0..12164ef 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "require": { "php": ">=8.3", "composer-runtime-api": "^2.2", - "nikic/php-parser": "^4.18" + "nikic/php-parser": "^4.18", + "symfony/console": "^7.0" } } diff --git a/src/Cli.php b/src/Cli.php deleted file mode 100644 index a24b5b4..0000000 --- a/src/Cli.php +++ /dev/null @@ -1,28 +0,0 @@ -"); - $outfile = $argv[2] ?? null; - $ext = self::loadExtension($name); - $code = StubsGenerator::generate($ext); - if (!$outfile) { - echo $code, "\n"; - } else { - $file = new \SplFileObject($outfile, 'w'); - $file->fwrite($code); - } - return 0; - } - - private static function loadExtension(string $name): ReflectionExtension - { - return new ReflectionExtension($name); - } -} diff --git a/src/Command/GenerateStubsCommand.php b/src/Command/GenerateStubsCommand.php new file mode 100644 index 0000000..7dd9391 --- /dev/null +++ b/src/Command/GenerateStubsCommand.php @@ -0,0 +1,37 @@ +setDescription('Generates IDE stubs for an extension.') + ->addArgument('extension', InputArgument::REQUIRED, 'The name of the extension') + ->addArgument('output-file', InputArgument::OPTIONAL, 'The output file path') + ; + } + + #[\Override] + protected function execute(InputInterface $input, OutputInterface $output): int + { + $ext = new ReflectionExtension($input->getArgument('extension')); + $code = StubsGenerator::generate($ext); + if ($outputPath = $input->getArgument('output-file')) { + $file = new \SplFileObject($outputPath, 'w'); + $file->fwrite($code); + } else { + $output->writeln($code); + } + return Command::SUCCESS; + } +} diff --git a/src/Command/ListExtensionsCommand.php b/src/Command/ListExtensionsCommand.php new file mode 100644 index 0000000..db60ae3 --- /dev/null +++ b/src/Command/ListExtensionsCommand.php @@ -0,0 +1,27 @@ +setDescription('Lists installed extensions.') + ; + } + + #[\Override] + protected function execute(InputInterface $input, OutputInterface $output): int + { + foreach (get_loaded_extensions() as $name) { + $output->writeln($name); + } + return Command::SUCCESS; + } +} diff --git a/src/Internal/AstBuilder.php b/src/Internal/AstBuilder.php index 25e4887..1812b2d 100644 --- a/src/Internal/AstBuilder.php +++ b/src/Internal/AstBuilder.php @@ -58,9 +58,7 @@ private function buildNamespace(ReflectionNamespace $namespace): Stmt\Namespace_ default => $name, }); foreach ($namespace->getConstants() as $name => $value) { - $builder->addStmt(new Stmt\Const_([ - new Node\Const_($name, $this->builderFactory->val($value)), - ])); + $builder->addStmt($this->buildConstant($name, $value)); } foreach ($namespace->getFunctions() as $function) { $builder->addStmt($this->buildFunction($function)); @@ -77,6 +75,13 @@ private function buildNamespace(ReflectionNamespace $namespace): Stmt\Namespace_ return $builder->getNode(); } + private function buildConstant(string $name, mixed $value): Stmt\Const_ + { + return new Stmt\Const_([ + new Node\Const_($name, $this->builderFactory->val($value)), + ]); + } + private function buildFunction(ReflectionFunction $function): Stmt\Function_ { $builder = $this->builderFactory->function($function->getShortName()); diff --git a/tests/Command/GenerateStubsTest.php b/tests/Command/GenerateStubsTest.php new file mode 100644 index 0000000..2f1d979 --- /dev/null +++ b/tests/Command/GenerateStubsTest.php @@ -0,0 +1,39 @@ +execute(['extension' => 'json']); + $tester->assertCommandIsSuccessful(); + $output = $tester->getDisplay(); + Assert::assertStringContainsString('function json_encode(', $output); + } + + public function testItWritesStubsToFile(): void + { + $guard = new TemporaryFileGuard(); + $cmd = new GenerateStubsCommand('stub'); + $tester = new CommandTester($cmd); + // json extension is a PHPUnit dependency, so should always be present in this environment. + $tester->execute([ + 'extension' => 'json', + 'output-file' => $guard->path, + ]); + $tester->assertCommandIsSuccessful(); + + Assert::assertFileExists($guard->path); + Assert::assertStringContainsString('function json_encode(', $guard->getContents()); + } +} diff --git a/tests/Command/ListExtensionsTest.php b/tests/Command/ListExtensionsTest.php new file mode 100644 index 0000000..75ce9bb --- /dev/null +++ b/tests/Command/ListExtensionsTest.php @@ -0,0 +1,18 @@ +execute([]); + $tester->assertCommandIsSuccessful(); + } +} diff --git a/tests/ExtensionAttributesTest.php b/tests/Generator/AttributesTest.php similarity index 90% rename from tests/ExtensionAttributesTest.php rename to tests/Generator/AttributesTest.php index 18c5780..864dde6 100644 --- a/tests/ExtensionAttributesTest.php +++ b/tests/Generator/AttributesTest.php @@ -1,13 +1,14 @@ path = tempnam(sys_get_temp_dir(), $prefix); + } + + public function getContents(): string + { + return file_get_contents($this->path); + } + + public function __destruct() + { + @unlink($this->path); + } +}