Behavior and usage updates.

This commit is contained in:
Bez Hermoso 2014-07-31 12:27:40 -07:00
parent ea41c41c7c
commit 0e01a00aaf
2 changed files with 49 additions and 61 deletions

View File

@ -11,16 +11,17 @@
namespace Nelmio\ApiDocBundle\Command; namespace Nelmio\ApiDocBundle\Command;
use Nelmio\ApiDocBundle\Formatter\SwaggerFormatter;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
/** /**
* Symfony2 command to dump Swagger-compliant JSON files. * Console command to dump Swagger-compliant API definitions.
* *
* @author Bez Hermoso <bez@activelamp.com> * @author Bez Hermoso <bez@activelamp.com>
*/ */
@ -31,17 +32,21 @@ class SwaggerDumpCommand extends ContainerAwareCommand
*/ */
protected $filesystem; protected $filesystem;
protected $destination; /**
* @var SwaggerFormatter
*/
protected $formatter;
protected function configure() protected function configure()
{ {
$this->filesystem = new Filesystem(); $this->filesystem = new Filesystem();
$this $this
->setDescription('Dump Swagger-compliant JSON files.') ->setDescription('Dumps Swagger-compliant API definitions.')
->addOption('resource', '', InputOption::VALUE_OPTIONAL, 'A specific resource API declaration to dump.') ->addOption('resource', 'r', InputOption::VALUE_OPTIONAL, 'A specific resource API declaration to dump.')
->addOption('list-only', '', InputOption::VALUE_NONE, 'Dump resource list only.') ->addOption('list-only', 'l', InputOption::VALUE_NONE, 'Dump resource list only.')
->addArgument('destination', InputOption::VALUE_OPTIONAL, 'Directory to dump JSON files in.', null) ->addOption('pretty', 'p', InputOption::VALUE_NONE, 'Dump as prettified JSON.')
->addArgument('destination', InputArgument::OPTIONAL, 'Directory to dump JSON files in.', null)
->setName('api:swagger:dump'); ->setName('api:swagger:dump');
} }
@ -50,26 +55,7 @@ class SwaggerDumpCommand extends ContainerAwareCommand
$container = $this->getContainer(); $container = $this->getContainer();
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor'); $extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
$this->formatter = $container->get('nelmio_api_doc.formatter.swagger_formatter');
$destination = $input->getArgument('destination');
if (count($destination) > 0) {
$destination = $destination[0];
$realpath = realpath($destination);
if ($realpath == false) {
$rootDir = $container->getParameter('kernel.root_dir');
$rootDir = realpath($rootDir . '/..');
$destination = $rootDir . '/' . $destination;
} else {
$destination = $realpath;
}
$this->destination = $destination;
} else {
$this->destination = null;
}
if ($input->getOption('list-only') && $input->getOption('resource')) { if ($input->getOption('list-only') && $input->getOption('resource')) {
throw new \RuntimeException('Cannot selectively dump a resource with the --list-only flag.'); throw new \RuntimeException('Cannot selectively dump a resource with the --list-only flag.');
@ -92,9 +78,12 @@ class SwaggerDumpCommand extends ContainerAwareCommand
return; return;
} }
/*
* If --list-only and --resource is not specified, dump everything.
*/
$data = $this->getResourceList($apiDocs); $data = $this->getResourceList($apiDocs);
if ($this->destination == null) { if (!$input->getArguments('destination')) {
$output->writeln(''); $output->writeln('');
$output->writeln('<comment>Resource list: </comment>'); $output->writeln('<comment>Resource list: </comment>');
} }
@ -104,7 +93,7 @@ class SwaggerDumpCommand extends ContainerAwareCommand
foreach ($data['apis'] as $api) { foreach ($data['apis'] as $api) {
$resource = substr($api['path'], 1); $resource = substr($api['path'], 1);
if ($this->destination == null) { if (!$input->getArgument('destination')) {
$output->writeln(''); $output->writeln('');
$output->writeln(sprintf('<comment>API declaration for <info>"%s"</info> resource: </comment>', $resource)); $output->writeln(sprintf('<comment>API declaration for <info>"%s"</info> resource: </comment>', $resource));
} }
@ -115,61 +104,60 @@ class SwaggerDumpCommand extends ContainerAwareCommand
protected function dump(array $data, $resource, InputInterface $input, OutputInterface $output, $treatAsFile = true) protected function dump(array $data, $resource, InputInterface $input, OutputInterface $output, $treatAsFile = true)
{ {
$destination = $input->getArgument('destination');
$content = json_encode($data, JSON_PRETTY_PRINT); $content = json_encode($data, $input->getOption('pretty') ? JSON_PRETTY_PRINT : 0);
if ($this->destination == null) { if (!$destination) {
$output->writeln($content); $output->writeln($content);
return; return;
} }
if ($resource == false) {
if ($treatAsFile === false) { if ($treatAsFile === false) {
$path = sprintf('%s/api-docs.json', $this->destination); if (!$this->filesystem->exists($destination)) {
} else { $this->filesystem->mkdir($destination);
$path = $this->destination;
} }
$string = sprintf('<comment>Dumping resource list to %s: </comment>', $path); }
$this->writeToFile($data, $path, $output, $string);
if (!$resource) {
if (!$treatAsFile) {
$destination = sprintf('%s/api-docs.json', rtrim($destination, '\\/'));
}
$message = sprintf('<comment>Dumping resource list to %s: </comment>', $destination);
$this->writeToFile($content, $destination, $output, $message);
return; return;
} }
if ($treatAsFile === false) { if ($treatAsFile === false) {
$path = sprintf('%s/%s.json', $this->destination, $resource); $destination = sprintf('%s/%s.json', rtrim($destination, '\\/'), $resource);
} else {
$path = $this->destination;
} }
$string = sprintf('<comment>Dump API declaration to %s: </comment>', $path);
$this->writeToFile($content, $path, $output, $string); $message = sprintf('<comment>Dump API declaration to %s: </comment>', $destination);
$this->writeToFile($content, $destination, $output, $message);
} }
protected function writeToFile($content, $file, OutputInterface $output, $string = null) protected function writeToFile($content, $file, OutputInterface $output, $message)
{ {
$message = array($string);
try { try {
$this->filesystem->dumpFile($file, $content); $this->filesystem->dumpFile($file, $content);
$message[] = '<info>OK</info>'; $message .= ' <info>OK</info>';
$output->writeln(implode(' ', array_filter($message)));
} catch (IOException $e) { } catch (IOException $e) {
$message[] = '<error>NOT OK</error>'; $message .= sprintf(' <error>NOT OK - %s</error>', $e->getMessage());
$output->writeln(implode(' ', array_filter($message)));
} }
$output->writeln($message);
} }
protected function getResourceList(array $data) protected function getResourceList(array $data)
{ {
$container = $this->getContainer(); return $this->formatter->format($data);
$formatter = $container->get('nelmio_api_doc.formatter.swagger_formatter');
$list = $formatter->format($data);
return $list;
} }
protected function getApiDeclaration(array $data, $resource) protected function getApiDeclaration(array $data, $resource)
{ {
$container = $this->getContainer(); return $this->formatter->format($data, '/' . $resource);
$formatter = $container->get('nelmio_api_doc.formatter.swagger_formatter');
$list = $formatter->format($data, '/' . $resource);
return $list;
} }
} }

View File

@ -80,7 +80,7 @@ Et voila!, simply specify http://yourdomain.com/api-docs in your Swagger client
The routes registered with the method above will read your `@ApiDoc` annotation during every request. Naturally, this will be slow because the bundle will parse your annotations every single time. For improved performance, you might be better off dumping the JSON output to the file-system and let your web-server serve them directly. If you want that, execute this command: The routes registered with the method above will read your `@ApiDoc` annotation during every request. Naturally, this will be slow because the bundle will parse your annotations every single time. For improved performance, you might be better off dumping the JSON output to the file-system and let your web-server serve them directly. If you want that, execute this command:
``` ```
php app/console api:swagger:dump --all app/Resources/swagger-docs php app/console api:swagger:dump app/Resources/swagger-docs
``` ```
The above command will dump JSON files under the `app/Resources/swagger-docs` directory (relative to your project root), and you can now process or server the files however you want. The destination defaults to the project root if not specified. The above command will dump JSON files under the `app/Resources/swagger-docs` directory (relative to your project root), and you can now process or server the files however you want. The destination defaults to the project root if not specified.
@ -89,12 +89,12 @@ The above command will dump JSON files under the `app/Resources/swagger-docs` di
Dump the `api-docs.json` resource list file only: Dump the `api-docs.json` resource list file only:
``` ```
php app/console api:swagger:dump --list-only php app/console api:swagger:dump --list-only api-docs.json
``` ```
Dump a specific resource API declaration only: Dump a specific resource API declaration only:
``` ```
php app/console api:swagger:dump --resource=users php app/console api:swagger:dump --resource=users users.json
``` ```
The above command will dump the `/users` API declaration in an `users.json` file. The above command will dump the `/users` API declaration in an `users.json` file.