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 #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 aa8640a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -10,13 +10,15 @@
- ISPManager recipe and docs.
- Symfony 5 recipe.
- Command for checking if a deploy is unlocked. [#2150] [#2150]
- `runLocally` function now accepts string or a Closure as first parameter [#2170]

### Fixed
- Normalize CRLF to LF new line endings. [#2111]
- Recipe for Magento now supports locale configuration for `setup:static-content:deploy`. [#2040]
- When symfony_env is set to dev, require-dev are not installed. [#2035]
- Fixed exit status of rollback command when there are no releases to rollback to. [#2052]
- When the second parameter $options passed to run() and runLocally(), use it to overwrite default env config. [#2165]
- Fixed `recipe/check_remote.php` calling `get('bin/php)` in remote host context twice [#2170]


## v6.8.0
Expand Down Expand Up @@ -582,7 +584,7 @@
- Fixed typo3 recipe.
- Fixed remove of shared dir on first deploy.


[#2170]: https://github.com/deployphp/deployer/issues/2170
[#2165]: https://github.com/deployphp/deployer/issues/2165
[#2150]: https://github.com/deployphp/deployer/issues/2150
[#2111]: https://github.com/deployphp/deployer/pull/2111
Expand Down
5 changes: 4 additions & 1 deletion recipe/deploy/check_remote.php
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
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 aa8640a

Please sign in to comment.