Test Failed
Push — master ( 114cec...08f770 )
by Divine Niiquaye
14:45 queued 02:19
created

WorkflowDumpCommand::complete()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of DivineNii opensource projects.
7
 *
8
 * PHP version 7.4 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 DivineNii (https://divinenii.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Rade\Commands\Symfony;
19
20
use Symfony\Component\Console\Command\Command;
21
use Symfony\Component\Console\Completion\CompletionInput;
22
use Symfony\Component\Console\Completion\CompletionSuggestions;
23
use Symfony\Component\Console\Exception\InvalidArgumentException;
24
use Symfony\Component\Console\Input\InputArgument;
25
use Symfony\Component\Console\Input\InputInterface;
26
use Symfony\Component\Console\Input\InputOption;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Symfony\Component\Workflow\Definition;
29
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
30
use Symfony\Component\Workflow\Dumper\MermaidDumper;
31
use Symfony\Component\Workflow\Dumper\PlantUmlDumper;
32
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;
33
use Symfony\Component\Workflow\Marking;
34
35
/**
36
 * @author Grégoire Pineau <[email protected]>
37
 *
38
 * @final
39
 */
40
class WorkflowDumpCommand extends Command
41
{
42
    protected static $defaultName = 'workflow:dump';
43
    protected static $defaultDescription = 'Dump a workflow';
44
45
    /**
46
     * string is the service id.
47
     *
48
     * @var array<string,Definition>
49
     */
50
    private array $workflows = [];
51
52
    private const DUMP_FORMAT_OPTIONS = ['puml', 'mermaid', 'dot'];
53
54
    /**
55
     * @param array<string,Definition> $workflows
56
     */
57
    public function __construct(array $workflows)
58
    {
59
        parent::__construct();
60
        $this->workflows = $workflows;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    protected function configure(): void
67
    {
68
        $this
69
            ->setDefinition([
70
                new InputArgument('name', InputArgument::REQUIRED, 'A workflow name'),
71
                new InputArgument('marking', InputArgument::IS_ARRAY, 'A marking (a list of places)'),
72
                new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Label a graph'),
73
                new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format [' . \implode('|', self::DUMP_FORMAT_OPTIONS) . ']', 'dot'),
74
            ])
75
            ->setHelp(
76
                <<<'EOF'
77
The <info>%command.name%</info> command dumps the graphical representation of a
78
workflow in different formats
79
80
<info>DOT</info>:  %command.full_name% <workflow name> | dot -Tpng > workflow.png
81
<info>PUML</info>: %command.full_name% <workflow name> --dump-format=puml | java -jar plantuml.jar -p > workflow.png
82
<info>MERMAID</info>: %command.full_name% <workflow name> --dump-format=mermaid | mmdc -o workflow.svg
83
EOF
84
            )
85
        ;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    protected function execute(InputInterface $input, OutputInterface $output): int
92
    {
93
        $workflowName = $input->getArgument('name');
94
95
        $workflow = null;
96
97
        if (isset($this->workflows['workflow.' . $workflowName])) {
98
            $workflow = $this->workflows['workflow.' . $workflowName];
99
            $type = 'workflow';
100
        } elseif (isset($this->workflows['state_machine.' . $workflowName])) {
101
            $workflow = $this->workflows['state_machine.' . $workflowName];
102
            $type = 'state_machine';
103
        }
104
105
        if (null === $workflow) {
106
            throw new InvalidArgumentException(\sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $workflowName));
107
        }
108
109
        switch ($input->getOption('dump-format')) {
110
            case 'puml':
111
                $transitionType = 'workflow' === $type ? PlantUmlDumper::WORKFLOW_TRANSITION : PlantUmlDumper::STATEMACHINE_TRANSITION;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
112
                $dumper = new PlantUmlDumper($transitionType);
113
114
                break;
115
116
            case 'mermaid':
117
                $transitionType = 'workflow' === $type ? MermaidDumper::TRANSITION_TYPE_WORKFLOW : MermaidDumper::TRANSITION_TYPE_STATEMACHINE;
118
                $dumper = new MermaidDumper($transitionType);
119
120
                break;
121
122
            case 'dot':
123
            default:
124
                $dumper = ('workflow' === $type) ? new GraphvizDumper() : new StateMachineGraphvizDumper();
125
        }
126
127
        $marking = new Marking();
128
129
        foreach ($input->getArgument('marking') as $place) {
130
            $marking->mark($place);
131
        }
132
133
        $options = [
134
            'name' => $workflowName,
135
            'nofooter' => true,
136
            'graph' => [
137
                'label' => $input->getOption('label'),
138
            ],
139
        ];
140
        $output->writeln($dumper->dump($workflow, $marking, $options));
141
142
        return self::SUCCESS;
143
    }
144
145
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
146
    {
147
        if ($input->mustSuggestArgumentValuesFor('name')) {
148
            $suggestions->suggestValues(\array_keys($this->workflows));
149
        }
150
151
        if ($input->mustSuggestOptionValuesFor('dump-format')) {
152
            $suggestions->suggestValues(self::DUMP_FORMAT_OPTIONS);
153
        }
154
    }
155
}
156