. */ namespace Irstea\PlantUmlBundle\Command; use Irstea\PlantUmlBundle\Model\Graph; use Irstea\PlantUmlBundle\Writer\StreamWriter; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Process\ExecutableFinder; /** * Description of ImportAffiliationCommand. */ class RenderCommand extends ContainerAwareCommand { protected function configure() { $this ->setName('irstea:plantuml:render') ->setDescription("Créer la page d'un graphe ou plusieurs graphes.") ->addOption('output', 'o', InputOption::VALUE_REQUIRED, 'Répertoire de destination.') ->addOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format du fichier à générer') ->addArgument('graph', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Graphe à générer'); } /** * @param InputInterface $input * @param OutputInterface $output * @SuppressWarnings(UnusedFormalParameter) */ protected function execute(InputInterface $input, OutputInterface $output) { $graphs = $input->getArgument('graph') ?: $this->getContainer()->getParameter('irstea_plant_uml.graph_keys'); $format = $input->getOption('format') ?: $this->getContainer()->getParameter('irstea_plant_uml.output.format'); $outputDir = $input->getOption('output') ?: $this->getContainer()->getParameter('irstea_plant_uml.output.directory'); $io = new SymfonyStyle($input, $output); foreach ($graphs as $name) { $target = $outputDir . DIRECTORY_SEPARATOR . $name . '.' . $format; $io->section("Graphe: $name"); $graph = $this->getContainer()->get("irstea_plant_uml.graph.$name"); $this->renderGraph($graph, $target, $format, $io); } } /** * @param Graph $graph * @param $target * @param $format * @param SymfonyStyle $io */ private function renderGraph(Graph $graph, $target, $format, SymfonyStyle $io): void { $io->writeln("Fichier de sortie: $target"); if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $io->getVerbosity()) { $desc = []; $graph->toConfig($desc); $io->writeln(json_encode($desc, JSON_PRETTY_PRINT)); } $io->write('Exploration des classes: '); $graph->visitAll(); $io->writeln('Ok.'); $io->write('Démarrage de PlantUML: '); list($proc, $pipes) = $this->startProcess($target, $format); $io->writeln('Ok.'); $io->write('Génération du graphe: '); $writer = new StreamWriter($pipes[0]); $graph->writeTo($writer); fclose($pipes[0]); $io->writeln('Ok.'); $io->write('Rendu graphique par PlantUML: '); $res = proc_close($proc); if ($res === 0) { $io->writeln('Ok.'); } else { $io->writeln('Nok.'); } } /** * @param $target * @param $format * @return array */ private function startProcess($target, $format): array { $ctn = $this->getContainer(); $javaBin = $this->findExecutable($ctn->getParameter('irstea_plant_uml.binaries.java')); $dotBin = $this->findExecutable($ctn->getParameter('irstea_plant_uml.binaries.dot')); $fs = new Filesystem(); $fs->mkdir(dirname($target)); $cmd = implode( ' ', [ $javaBin, '-jar', $ctn->getParameter('irstea_plant_uml.binaries.plamtuml_jar'), '-graphvizdot', $dotBin, '-pipe', '-t' . $format, ] ); $desc = [ // stdin ['pipe', 'r'], // stdout ['file', $target, 'wt'], // stderr STDERR, ]; $pipes = []; $proc = proc_open($cmd, $desc, $pipes); return [$proc, $pipes]; } /** * @param string $nameOrPath * @return string */ private function findExecutable(string $nameOrPath): string { if (\file_exists($nameOrPath) && \is_executable($nameOrPath)) { return $nameOrPath; } $exec = new ExecutableFinder(); $path = $exec->find($nameOrPath); if ($path === null) { throw new \RuntimeException("cannot find executable: $nameOrPath"); } return $path; } }