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