TaskRunner   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 62
rs 10
c 0
b 0
f 0
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A run() 0 8 2
B doRun() 0 38 6
1
<?php
2
3
4
namespace Bencagri\Artisan\Deployer\Task;
5
6
use Bencagri\Artisan\Deployer\Helper\Str;
7
use Bencagri\Artisan\Deployer\Logger;
8
use Bencagri\Artisan\Deployer\Server\Property;
9
use Bencagri\Artisan\Deployer\Server\Server;
10
use Symfony\Component\Process\Process;
11
12
class TaskRunner
13
{
14
    private $isDryRun;
15
    private $logger;
16
17
    public function __construct(bool $isDryRun, Logger $logger)
18
    {
19
        $this->isDryRun = $isDryRun;
20
        $this->logger = $logger;
21
    }
22
23
    /**
24
     * @return TaskCompleted[]
25
     */
26
    public function run(Task $task) : array
27
    {
28
        $results = [];
29
        foreach ($task->getServers() as $server) {
30
            $results[] = $this->doRun($server, $server->resolveProperties($task->getShellCommand()), $task->getEnvVars());
31
        }
32
33
        return $results;
34
    }
35
36
    private function doRun(Server $server, string $shellCommand, array $envVars) : TaskCompleted
37
    {
38
        if ($server->has(Property::project_dir)) {
39
            $shellCommand = sprintf('cd %s && %s', $server->get(Property::project_dir), $shellCommand);
40
        }
41
42
        // env vars aren't set with $process->setEnv() because it causes problems
43
        // that can't be fully solved with inheritEnvironmentVariables()
44
        if (!empty($envVars)) {
45
            $envVarsAsString = http_build_query($envVars, '', ' ');
46
            // the ';' after the env vars makes them available to all commands, not only the first one
47
            // parenthesis create a sub-shell so the env vars don't affect to the parent shell
48
            $shellCommand = sprintf('(export %s; %s)', $envVarsAsString, $shellCommand);
49
        }
50
51
        $this->logger->log(sprintf('[<server>%s</>] Executing command: <command>%s</>', $server, $shellCommand));
52
53
        if ($this->isDryRun) {
54
            return new TaskCompleted($server, '', 0);
55
        }
56
57
        if ($server->isLocalHost()) {
58
            $process = new Process($shellCommand);
59
        } else {
60
            $process = new Process(sprintf('%s %s', $server->getSshConnectionString(), escapeshellarg($shellCommand)));
61
        }
62
63
        $process->setTimeout(null);
64
65
        $process = $process->mustRun(function ($type, $buffer) {
66
            if (Process::ERR === $type) {
67
                $this->logger->log(Str::prefix(rtrim($buffer, PHP_EOL), '| <stream>err ::</> '));
68
            } else {
69
                $this->logger->log(Str::prefix(rtrim($buffer, PHP_EOL), '| <stream>out ::</> '));
70
            }
71
        });
72
73
        return new TaskCompleted($server, $process->getOutput(), $process->getExitCode());
74
    }
75
}
76