An error occurred while loading the file. Please try again.
-
Guillaume Perréal authored32ba6c2c
<?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;
}
}