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
|
|
|
|