RenderCommand.php 6.50 KiB
<?php declare(strict_types=1);
/*
 * This file is part of "irstea/plantuml-bundle".
 * Copyright (C) 2016-2019 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\PlantUmlBundle\Command;
use Irstea\PlantUmlBundle\Model\Graph;
use Irstea\PlantUmlBundle\Writer\StreamWriter;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Command\Command;
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 Command
    /**
     * @var string
    private const CMD_NAME = 'irstea:plantuml:render';
    /**
     * @var ContainerInterface
    private $container;
    /**
     * @var string[]
    private $graphNames;
    /**
     * @var string
    private $defaultFormat;
    /**
     * @var string
    private $defaultOutput;
    /**
     * @var string
    private $javaBinary;
    /**
     * @var string
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
*/ private $plantUmlJar; /** * @var string */ private $dotBinary; /** * RenderCommand constructor. * * @param ContainerInterface $container * @param array $graphNames * @param string $defaultFormat * @param string $defaultOutput * @param string $javaBinary * @param string $plantUmlJar * @param string $dotBinary */ public function __construct(ContainerInterface $container, array $graphNames, string $defaultFormat, string $defaultOutput, string $javaBinary, string $plantUmlJar, string $dotBinary) { parent::__construct(self::CMD_NAME); $this->container = $container; $this->graphNames = $graphNames; $this->defaultFormat = $defaultFormat; $this->defaultOutput = $defaultOutput; $this->javaBinary = $javaBinary; $this->plantUmlJar = $plantUmlJar; $this->dotBinary = $dotBinary; } /** * {@inheritdoc} */ protected function configure(): void { $this ->setName(self::CMD_NAME) ->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'); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $graphs = $input->getArgument('graph') ?: $this->graphNames; $format = $input->getOption('format') ?: $this->defaultFormat; $outputDir = $input->getOption('output') ?: $this->defaultOutput; $io = new SymfonyStyle($input, $output); foreach ($graphs as $name) { $target = $outputDir . DIRECTORY_SEPARATOR . $name . '.' . $format; $io->section("Graphe: $name"); $graph = $this->container->get("irstea_plant_uml.graph.$name"); $this->renderGraph($graph, $target, $format, $io); } } /** * @param Graph $graph * @param $target * @param $format
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
* @param SymfonyStyle $io */ private function renderGraph(Graph $graph, $target, $format, SymfonyStyle $io): void { $io->writeln("Fichier de sortie: <comment>$target</comment>"); 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('<info>Ok</info>.'); $io->write('Démarrage de PlantUML: '); list($proc, $pipes) = $this->startProcess($target, $format); $io->writeln('<info>Ok</info>.'); $io->write('Génération du graphe: '); $writer = new StreamWriter($pipes[0]); $graph->writeTo($writer); fclose($pipes[0]); $io->writeln('<info>Ok</info>.'); $io->write('Rendu graphique par PlantUML: '); $res = proc_close($proc); if ($res === 0) { $io->writeln('<info>Ok</info>.'); } else { $io->writeln('<error>Nok</error>.'); } } /** * @param $target * @param $format * * @return array */ private function startProcess($target, $format): array { $cmd = sprintf( '%s -jar %s -graphvizdot %s -pipe -t%s', $this->findExecutable($this->javaBinary), $this->plantUmlJar, $this->findExecutable($this->dotBinary), $format ); $fs = new Filesystem(); $fs->mkdir(dirname($target)); $desc = [ // stdin ['pipe', 'r'], // stdout ['file', $target, 'wt'], // stderr STDERR, ]; $pipes = []; $proc = proc_open($cmd, $desc, $pipes); return [$proc, $pipes]; }
211212213214215216217218219220221222223224225226227228229230
/** * @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; } }