buildDummyClasses 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/env php
  2. <?php
  3. /*
  4. * This file is part of php-restcord.
  5. *
  6. * (c) Aaron Scherer <aequasi@gmail.com>
  7. *
  8. * This source file is subject to the license that is bundled
  9. * with this source code in the file LICENSE
  10. */
  11. function recursiveRemoveDirectory($directory)
  12. {
  13. foreach (glob("{$directory}/*") as $file) {
  14. if (is_dir($file)) {
  15. recursiveRemoveDirectory($file);
  16. } else {
  17. unlink($file);
  18. }
  19. }
  20. rmdir($directory);
  21. }
  22. $path = __DIR__.'/../src/Interfaces';
  23. try {
  24. recursiveRemoveDirectory($path);
  25. } catch (\Exception $e) {
  26. }
  27. mkdir($path, 02775, true);
  28. $path = realpath($path);
  29. require __DIR__.'/../vendor/autoload.php';
  30. use gossi\codegen\generator\CodeGenerator;
  31. use gossi\codegen\model\PhpInterface;
  32. use gossi\codegen\model\PhpMethod;
  33. use gossi\codegen\model\PhpParameter;
  34. use gossi\codegen\model\PhpProperty;
  35. use GuzzleHttp\Command\Result;
  36. use Symfony\Component\Console\Application;
  37. use Symfony\Component\Console\Input\InputArgument;
  38. use Symfony\Component\Console\Input\InputInterface;
  39. use Symfony\Component\Console\Output\OutputInterface;
  40. $loader = new Twig_Loader_Filesystem(__DIR__.'/../src/Resources/');
  41. $twig = new Twig_Environment($loader, ['debug' => true]);
  42. $twig->addExtension(new Twig_Extension_Debug());
  43. $license = <<<EOF
  44. <?php
  45. /*
  46. * Copyright 2017 Aaron Scherer
  47. *
  48. * This source file is subject to the license that is bundled
  49. * with this source code in the file LICENSE
  50. *
  51. * @package restcord/restcord
  52. * @copyright Aaron Scherer 2017
  53. * @license MIT
  54. */
  55. \n
  56. EOF;
  57. /** @noinspection PhpUnhandledExceptionInspection */
  58. (new Application('Build Dummy Classes', '1.0.0'))
  59. ->register('buildDummyClasses')
  60. ->addArgument('version', InputArgument::REQUIRED, 'Version to build')
  61. ->setCode(
  62. function (InputInterface $input, OutputInterface $output) use ($twig, $license, $path) {
  63. $style = new \Symfony\Component\Console\Style\SymfonyStyle($input, $output);
  64. $style->title("Building Dummy Classes for Gateway v".$input->getArgument('version'));
  65. $definition = \GuzzleHttp\json_decode(
  66. file_get_contents(
  67. __DIR__.'/../src/Resources/service_description-v'.$input->getArgument('version').'.json'
  68. ),
  69. true
  70. );
  71. $generator = new CodeGenerator();
  72. foreach ($definition['operations'] as $resource => $operations) {
  73. $resource = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $resource)));
  74. $class = new PhpInterface();
  75. $class->setQualifiedName('RestCord\\Interfaces\\'.ucwords($resource));
  76. $class->setDescription(ucwords($resource)." Intellisense Helper");
  77. $class->setMethods(
  78. array_map(
  79. function ($name, $operation) use ($class, $resource) {
  80. $options = new PhpParameter('options');
  81. $options->setType(
  82. 'array',
  83. '['.implode(
  84. ', ',
  85. array_map(
  86. function ($name, $parameter) {
  87. return "'".$name."' => '".$parameter['type']."'";
  88. },
  89. array_keys($operation['parameters']),
  90. $operation['parameters']
  91. )
  92. ).']'
  93. );
  94. $returnType = 'array';
  95. if (isset($operation['responseTypes']) && sizeof($operation['responseTypes']) >= 1) {
  96. $firstType = $operation['responseTypes'][0]['type'];
  97. $array = stripos($firstType, 'Array<') !== false;
  98. if ($array) {
  99. $firstType = substr($firstType, 6, -1);
  100. }
  101. $temp = explode("/", $firstType);
  102. $returnType = sprintf(
  103. "\\RestCord\\Model\\%s\\%s",
  104. str_replace(
  105. ' ',
  106. '',
  107. ucwords(str_replace('-', ' ', $temp[0]))
  108. ),
  109. str_replace(
  110. ' ',
  111. '',
  112. ucwords(str_replace('-', ' ', $temp[1]))
  113. )
  114. );
  115. $returnType = mapBadDocs($name, $operation, $returnType);
  116. if (!class_exists($returnType)) {
  117. $returnType = "\\".Result::class;
  118. }
  119. $returnType .= $array ? '[]' : '';
  120. }
  121. $method = new PhpMethod(
  122. lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $name))))
  123. );
  124. $method->setType($returnType, $operation['responseNote'] ?? '');
  125. if (isset($operation['link'])) {
  126. $method->setLongDescription('@see '.$operation['link']);
  127. }
  128. $method->setParameters([$options]);
  129. $method->setVisibility('public');
  130. return $method;
  131. },
  132. array_keys($operations),
  133. $operations
  134. )
  135. );
  136. file_put_contents($path.'/'.ucwords($resource).'.php', $license.$generator->generate($class));
  137. }
  138. $style->success('Finished. Classes built in: '.realpath($path));
  139. }
  140. )
  141. ->getApplication()
  142. ->setDefaultCommand('buildDummyClasses', true)
  143. ->run();
  144. function mapBadDocs(string $name, array $operation, string $cls): string
  145. {
  146. switch ($cls) {
  147. case '\RestCord\Model\User\DmChannel':
  148. $newCls = '\RestCord\Model\Channel\DmChannel';
  149. break;
  150. case '\RestCord\Model\Channel\Invite':
  151. case '\RestCord\Model\Guild\Invite':
  152. $newCls = '\RestCord\Model\Invite\Invite';
  153. break;
  154. case '\RestCord\Model\Guild\GuildChannel':
  155. $newCls = '\RestCord\Model\Channel\GuildChannel';
  156. break;
  157. case '\RestCord\Model\Guild\User':
  158. case '\RestCord\Model\Channel\User':
  159. $newCls = '\RestCord\Model\User\User';
  160. break;
  161. case 'ISO8601':
  162. case '\RestCord\Model\Channel\ISO8601':
  163. $newCls = '\DateTimeImmutable';
  164. break;
  165. default:
  166. return $cls;
  167. }
  168. trigger_error($name.' operation in '.$operation['resource'].' has a bad responseType: '.$cls);
  169. return $newCls;
  170. }