Skip to content

Commit

Permalink
[issue-2170] Modified runLocally function to accept closure
Browse files Browse the repository at this point in the history
As noted in the issue deployphp#2170, the logic in the recipe/check_remote.php
would try to get the binary path of local and remote git executable.

However, due to specific implementation, the get('bin/git') would
have been called twice in the context of remote host, instead of
invoking it once on remote and once on local machine.

The runLocally function has thus been reworked, to accept Closure,
which will be invoked in the context of the localhost machine.
Once a Closure has been passed, the function will push the Localhost
to the Context, invoke the closure, store the stdout (if available),
pop the Localhost from the Context and finally return the stdout.

For compatibility reasons, the function also accepts the string argument,
however it is wrapped in a closure and once again passed to the runLocally
function.

The recipe/check_remote.php file has been reworked, to utilize the Closure,
to make sure that the get('bin/git') is being called in the Localhost context.
  • Loading branch information
bsacharski committed Sep 26, 2020
1 parent 44f5f84 commit f1a250d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
5 changes: 4 additions & 1 deletion recipe/deploy/check_remote.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
$opt = '--heads';
}

$remoteLs = runLocally(sprintf("%s ls-remote $opt $repository $ref", get('bin/git')));
$remoteLs = runLocally(function () use ($opt, $repository, $ref) {
$cmd = sprintf("%s ls-remote $opt $repository $ref", get('bin/git'));
return run($cmd);
});
if (strstr($remoteLs, "\n")) {
throw new Exception("Could not determine target revision. '$ref' matched multiple commits.");
}
Expand Down
40 changes: 30 additions & 10 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Deployer;

use Closure;
use Deployer\Exception\Exception;
use Deployer\Exception\GracefulShutdownException;
use Deployer\Exception\RunException;
Expand Down Expand Up @@ -339,24 +340,43 @@ function run($command, $options = [])
/**
* Execute commands on local machine
*
* @param string $command Command to run locally.
* @param string|Closure $command Command to run locally, or a closure that will be executed in local machine context
* @param array $options
* @return string Output of command.
*/
function runLocally($command, $options = [])
{
$process = Deployer::get()->processRunner;
$command = parse($command);
if ($command instanceof Closure) {
$input = Context::has() ? input() : null;
$output = Context::has() ? output() : null;

$env = array_merge_alternate(get('env', []), $options['env'] ?? []);
if (!empty($env)) {
$env = array_to_string($env);
$command = "export $env; $command";
}
$localhostContext = new Context(new Localhost(), $input, $output);
Context::push($localhostContext);
try {
$output = $command();
if (!is_string($output)) {
$output = '';
}
} finally {
Context::pop();
}

$output = rtrim($output);
return $output;
} else {
$command = parse($command);
$env = array_merge_alternate(get('env', []), $options['env'] ?? []);

$output = $process->run(new Localhost(), $command, $options);
return runLocally(function () use ($command, $options, $env) {
if (!empty($env)) {
$env = array_to_string($env);
$command = "export $env; $command";
}

return rtrim($output);
$output = run($command, $options);
return $output;
});
}
}

/**
Expand Down

0 comments on commit f1a250d

Please sign in to comment.