Failed Conditions
Push — 0.3 ( 530096...907796 )
by jean
04:25 queued 10s
created

LaunchIsolateProcessStep::execute()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 30
nc 8
nop 1
dl 0
loc 45
ccs 31
cts 31
cp 1
crap 4
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Darkilliant\ProcessBundle\Step;
6
7
use Darkilliant\ProcessBundle\State\ProcessState;
8
use Symfony\Component\Console\ConsoleEvents;
9
use Symfony\Component\Console\Event\ConsoleEvent;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12
use Symfony\Component\OptionsResolver\OptionsResolver;
13
use Symfony\Component\Process\PhpExecutableFinder;
14
use Symfony\Component\Process\Process;
15
use Symfony\Component\Process\ProcessBuilder;
16
17
class LaunchIsolateProcessStep extends AbstractConfigurableStep implements EventSubscriberInterface
18
{
19
    private $processCollection = [];
20
    private $verbosity;
21
    private $environment;
22
23 7
    public function __construct($environment)
24
    {
25 7
        $this->environment = $environment;
26 7
    }
27
28
    /**
29
     * @codeCoverageIgnore
30
     */
31
    public static function getSubscribedEvents()
32
    {
33
        return [
34
            ConsoleEvents::COMMAND => ['onCommand', 255],
35
        ];
36
    }
37
38 5
    public function onCommand(ConsoleEvent $event)
39
    {
40 5
        $this->verbosity = $event->getOutput()->getVerbosity();
41 5
    }
42
43 1
    public function configureOptionResolver(OptionsResolver $resolver): OptionsResolver
44
    {
45 1
        $resolver->setRequired(['process_name', 'max_concurency', 'context', 'data', 'timeout', 'bin_console_path']);
46 1
        $resolver->setDefault('context', []);
47 1
        $resolver->setDefault('data', []);
48 1
        $resolver->setDefault('max_concurency', 1);
49 1
        $resolver->setDefault('timeout', 60 * 20);
50
51 1
        return parent::configureOptionResolver($resolver);
52
    }
53
54 6
    public function execute(ProcessState $state)
55
    {
56 6
        $processName = $state->getOptions()['process_name'];
57 6
        $maxConcurency = $state->getOptions()['max_concurency'];
58 6
        $context = $state->getOptions()['context'];
59 6
        $data = $state->getOptions()['data'];
60
61 6
        $processBuilder = $this->getProcessBuilder();
62 6
        $phpFinder = $this->getPhpExecutableFinder();
63
64
        $arguments = [
65 6
            $phpFinder->find(),
66 6
            $state->getOptions()['bin_console_path'],
67 6
            'process:run',
68 6
            '--env=prod',
69 6
            '--input-from-stdin',
70 6
            '--force-color',
71
        ];
72
73 6
        $verbosityParameter = $this->getVerbosityParameter();
74 6
        if ($verbosityParameter) {
75 5
            $arguments[] = $verbosityParameter;
76
        }
77
78 6
        foreach ($context as $key => $value) {
79 6
            $arguments[] = sprintf('--context %s=%s', $key, $value);
80
        }
81
82 6
        $arguments[] = '--';
83 6
        $arguments[] = $processName;
84 6
        $processBuilder->setArguments($arguments);
85
86 6
        $processBuilder->setInput(json_encode($data));
87 6
        $processBuilder->setTimeout($state->getOptions()['timeout']);
88 6
        $processBuilder->disableOutput();
89 6
        $process = $processBuilder->getProcess();
90
91 6
        $this->processCollection[] = $process;
92
93 6
        $process->start(function ($type, $output) {
94 6
            echo $output;
95 6
        });
96
97 6
        if (count($this->processCollection) >= $maxConcurency) {
98 6
            $this->wait();
99
        }
100 6
    }
101
102 6
    public function finalize(ProcessState $state)
103
    {
104 6
        $this->wait();
105 6
    }
106
107
    /**
108
     * @codeCoverageIgnore
109
     */
110
    protected function getProcessBuilder(): ProcessBuilder
111
    {
112
        return new ProcessBuilder();
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Process\ProcessBuilder has been deprecated: since version 3.4, to be removed in 4.0. Use the Process class instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

112
        return /** @scrutinizer ignore-deprecated */ new ProcessBuilder();
Loading history...
113
    }
114
115
    /**
116
     * @codeCoverageIgnore
117
     */
118
    protected function getPhpExecutableFinder(): PhpExecutableFinder
119
    {
120
        return new PhpExecutableFinder();
121
    }
122
123 6
    protected function getVerbosityParameter()
124
    {
125 6
        if (!$this->verbosity) {
126 1
            return '-vv';
127
        }
128 5
        switch ($this->verbosity) {
129 5
            case OutputInterface::VERBOSITY_QUIET:
130 1
                return '-q';
131 4
            case OutputInterface::VERBOSITY_VERBOSE:
132 1
                return '-v';
133 3
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
134 1
                return '-vv';
135 2
            case OutputInterface::VERBOSITY_DEBUG:
136 1
                return '-vvv';
137
        }
138
139 1
        return null;
140
    }
141
142 6
    private function wait()
143
    {
144 6
        foreach ($this->processCollection as $process) {
145
            /* @var Process $process */
146 6
            $process->wait();
147
        }
148 6
        $this->processCollection = [];
149 6
    }
150
}
151