<?php declare(strict_types=1); /* * This file is part of "irstea/ng-model-generator-bundle". * * "irstea/ng-model-generator-bundle" generates Typescript interfaces for Angular using api-platform metadata. * Copyright (C) 2018-2021 IRSTEA * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License and the GNU * Lesser General Public License along with this program. If not, see * <https://www.gnu.org/licenses/>. */ namespace Irstea\NgModelGeneratorBundle\Command; use ApiPlatform\Core\Documentation\Documentation; use Assert\Assertion; use Irstea\NgModelGeneratorBundle\ModelGenerator; use Irstea\NgModelGeneratorBundle\Writers\ConsoleWriter; use Irstea\NgModelGeneratorBundle\Writers\DirectoryWriter; use Irstea\NgModelGeneratorBundle\Writers\FilteringFileWriter; use Irstea\NgModelGeneratorBundle\Writers\MultiFileWriter; use Irstea\NgModelGeneratorBundle\Writers\PhonyFileWriter; use Irstea\NgModelGeneratorBundle\Writers\ZipWriter; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** * Class NgModelGenerateCommand. */ /* final */ class NgModelGenerateCommand extends Command { /** * @var ModelGenerator */ private $generator; /** * @var Documentation */ private $documentation; /** * NgModelGenerateCommand constructor. */ public function __construct( ModelGenerator $generator, Documentation $documentation ) { parent::__construct(); $this->generator = $generator; $this->documentation = $documentation; } /** * {@inheritdoc} */ protected function configure(): void { $this ->setName('ng-model:generate') ->setDescription('Dump Typescript representations') ->addOption('zip', 'z', InputOption::VALUE_REQUIRED, 'Archive ZIP à créer') ->addOption('output', 'o', InputOption::VALUE_REQUIRED, 'Dossier de destination') ->addOption('force', 'f', InputOption::VALUE_NONE, 'Ecrase la cible') ->addOption('restrict', 'r', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Limite la sortie aux modèles de nom de fichier'); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output): void { $writer = new PhonyFileWriter( $this->openWriter($input, $output), $output ); if ($input->getOption('restrict')) { $globs = $input->getOption('restrict'); Assertion::isArray($globs); Assertion::allString($globs); $writer = new FilteringFileWriter($writer, function (string $path) use ($globs): bool { foreach ($globs as $glob) { if (fnmatch($glob, $path, \FNM_PATHNAME)) { return true; } } return false; }); } try { $this->generator->generate($this->documentation, $writer); } finally { $writer->close(); } } private function openWriter(InputInterface $input, OutputInterface $output): MultiFileWriter { $zipPath = $input->getOption('zip'); Assertion::nullOrString($zipPath); if ($zipPath) { $force = (bool) $input->getOption('force'); $archive = $this->openZipArchive($zipPath, $force); $output->write("Writing to ZIP archive: <info>$zipPath</info>\n"); return new ZipWriter($archive); } $dirPath = $input->getOption('output'); Assertion::nullOrString($dirPath); if ($dirPath) { $output->write("Writing to directory: <info>$dirPath</info>\n"); return new DirectoryWriter($dirPath); } return new ConsoleWriter($output); } private function openZipArchive(string $path, bool $force): \ZipArchive { $archive = new \ZipArchive(); $flags = \ZipArchive::CREATE; if ($force) { $flags |= \ZipArchive::OVERWRITE; } $res = $archive->open($path, $flags); if ($res !== true) { throw new \RuntimeException("Could not open $path, error code #$res"); } return $archive; } }